What is the 122 cbor tag

I see that in the jpg.store datum attached to offers there is a 122 cbor tag. The following is a snippet from the datum used in a collection offer:

121([_
    122([_
        h'84CC25EA4C29951D40B443B95BBC5676BC425470F96376D1984AF9AB'
    ]),
    121([_
        121([_
            122([_
                h'2C967F4BD28944B06462E13C5E3F5D5FA6E03F8567569438CD833E6D'
            ])
        ])
    ])
])

I noticed that Lucid fails to parse this datum using the following Data schema:

Data.Object({
    paymentCredential: Data.Object({ 
        pubKeyHash: Data.Bytes() 
    }),
    stakeCredential: Data.Object({
        container: Data.Object({ 
            container: Data.Object({
                stakeKeyHash: Data.Bytes()
            })
        }) 
    }),
})

However manually replacing the hex in the cbor to change the 122 tags for 121 tags fixes that issue, with the same Lucid schema. Is 122 not an object? Is there somewhere I can read up on these tags? thanks :slight_smile:

I’ll answer since I managed to figure this out. Seems a bit obvious in retrospect but none the less:
Starting with the 121 tag, it encodes the first constructor of a type, ie. Constr 0. Following on from that, the 122 tag encodes the second, ie. Constr 1, and so on.

Using some haskell type examples:

data Bool
  = False        -- Constr 0 []
  | True         -- Constr 1 []

data MyOption
  = Some Int     -- Constr 0 [...]
  | None         -- Constr 1 []

data MyEither
  = Left Int     -- Constr 0 [...]
  | Right String -- Constr 1 [...]

data Color
  = Red          -- Constr 0 []
  | Green        -- Constr 1 []
  | Blue         -- Constr 2 []

Therefore the example in my initial question is a case of having some “Eithers” and we can use Lucid’s Data.Enum() to successfully decode them like so:

const PubKeyCredential = { PubKeyCredential: { pubkeyhash: Data.Bytes()}};
const ScriptCredential = { ScriptCredential: { scripthash: Data.Bytes()}};

const Credential = Data.Enum(
    PubKeyCredential,
    ScriptCredential
)

const StakeCredential = Data.Nullable(Data.Object({ credential: Credential }))

const JpgDatumAddress = 
    Data.Object({
        paymentCredential: Credential,
        stakeCredential: StakeCredential
    })