gagliardetto / anchor-go

Generate Go clients from anchor IDLs for Solana blockchain programs
MIT License
138 stars 31 forks source link

Issue with complex enum type #15

Closed josephtaylor closed 1 year ago

josephtaylor commented 1 year ago

Hello! I'm trying to utilize anchor-go to generate code for some of the newer metaplex instructions.

Running into an issue with a new field they added to NFTs called CollectionDetails.

I used shank from metaplex to generate IDL from the token-metadata program, and the CollectionDetails field looks like:

    {
      "name": "CollectionDetails",
      "type": {
        "kind": "enum",
        "variants": [
          {
            "name": "V1",
            "fields": [
              {
                "name": "size",
                "type": "u64"
              }
            ]
          }
        ]
      }
    },

Which results in the following go code generated from anchor-go:

type CollectionDetails interface {
    isCollectionDetails()
}
​
type collectionDetailsContainer struct {
    Enum ag_binary.BorshEnum `borsh_enum:"true"`
    V1   CollectionDetailsV1
}
​
type CollectionDetailsV1 struct {
    Size uint64
}
​
func (obj CollectionDetailsV1) MarshalWithEncoder(encoder *ag_binary.Encoder) (err error) {
    // Serialize `Size` param:
    err = encoder.Encode(obj.Size)
    if err != nil {
        return err
    }
    return nil
}
​
func (obj *CollectionDetailsV1) UnmarshalWithDecoder(decoder *ag_binary.Decoder) (err error) {
    // Deserialize `Size`:
    err = decoder.Decode(&obj.Size)
    if err != nil {
        return err
    }
    return nil
}
​
func (_ *CollectionDetailsV1) isCollectionDetails() {}

Is that correct? What's the purpose of the isCollectionDetails() function? (sorry, new to anchor)

Then in my own code i'm trying to do something like:

       collectionDetails := token_metadata.CollectionDetailsV1{
        Size: 0,
    }
    var details *token_metadata.CollectionDetails
    details = &collectionDetails

And the compiler is getting upset saying that CollectionDetailsV1 can't be assigned to CollectionDetails even tho CollectionDetailsV1 definitely implements that interface.

Any help would be greatly appreciated. Thanks so much for these libraries!

gagliardetto commented 1 year ago
       collectionDetails := token_metadata.CollectionDetailsV1{
        Size: 0,
    }
    var details token_metadata.CollectionDetails
    details = &collectionDetails

token_metadata.CollectionDetails is an interface, and should be used without the pointer to it (note var details token_metadata.CollectionDetails).

josephtaylor commented 1 year ago

wow, sorry bout that.

I fixed that but didn't have much luck with my generated clients doing the CreateMetadataAccountV3 instruction, kept getting serialization errors. So i've fallen back to V2 for now which you've already got in metaplex-go

thanks again!