ValueDecoder for tuple and contract IDs

Hi. I am using the java bindings. I need to convert the Value returned by the ledger API in the exercise result for this choice into the correct type - Tuple2<Batch.ContractId, List<Instruction.ContractId>>. I assume I will need to use something like Tuple2.valueDecoder(?, ?) but not sure what the arguments should be.

Tuple2 takes two type parameters for the respective values in your tuple. The arguments to the Tuple2.valueDecoder are the decoders for those types. So if you have a Tuple2<String, Party> you need to pass value decoders for string and party.

Yes but how can I get value decoders for ContractId types mentioned above?

As you noticed over here, using the new strongly-typed command submission methods is the best way to get a choice exercise result decoded for you.

Otherwise, if you look at the code generated for CHOICE_Instruct, you can see how the return-type decoder used in the aforementioned command submission methods is assembled. With regard to concrete contract ID types, it should look something like

value -> new Batch.ContractId(
  value.asContractId()
    .orElseThrow(() -> new IllegalArgumentException("Batch"))
    .getValue())

Concrete contract-IDs are surely a missing piece of the combinator-library puzzle for assembling value decoders, but given the above pattern you can define a general-purpose decoder like so:

  // use like concreteContractIdValueDecoder(Batch.COMPANION)
  public static final <ContractType, Id>
      ValueDecoder<Id> concreteContractIdValueDecoder(
          ContractTypeCompanion<?, Id, ContractType, ?> companion) {
    return value ->
        companion.toContractId(
            new ContractId<>(
                value
                    .asContractId()
                    .orElseThrow(
                        () ->
                            new IllegalArgumentException(
                                companion.TEMPLATE_ID.getEntityName() + ".ContractId"))
                    .getValue()));
  }