dojoengine / dojo

Dojo is a toolchain for building provable games and autonomous worlds with Cairo
https://dojoengine.org
Apache License 2.0
407 stars 165 forks source link

Torii enum return type #2188

Closed rsodre closed 1 month ago

rsodre commented 2 months ago

Describe the bug

Not sure if this is a bug or is the designed way for Torii to work...

But when passing enums to system functions, we use their corresponding sequential numeric value. But Torii returns enum values as strings, the actual name of the value.

Is Torii correct in returning enum values as strings? Can/should Torii return enum values as numbers?

To Reproduce

Look at this query on dojo-starter, the value returned on last_direction is a string:

query {
  movesModels {
    edges {
      node {
            player
            last_direction
      }
    }
  }
}
{
  "data": {
    "movesModels": {
      "edges": [
        {
          "node": {
            "player": "0x34fdc2124fb1a4362ad6f1e09b8685075e8e37ded505177bc758ec81e4a66e8",
            "last_direction": "Right"
          }
        }
      ]
    }
  }
}

This is how we call the move() function passing a numeric Direction.

export enum Direction {
    Left = 1,
    Right = 2,
    Up = 3,
    Down = 4,
}

const move = async (account: AccountInterface, direction: Direction) => { 
  const { transaction_hash } = await client.actions.move({
    account,
    direction,
  });
 }

Expected behavior

I believe a cairo type should have just one corresponding client type. If there are multiple, they all should be supported on all ends.

Additional context

This is causing problems in my clients, I don't know what type an enum should have. I opened dojo.js issue #238 to adapt it when this issue is resolved.

Larkooo commented 2 months ago

Ah yes it is expected behaviour. On GraphQL, enums are represented as strings for their enum selected variant. Additional data within the enum variant is also returned but in that case, it is not considered.

Consider

enum Option<T> {
 Some: T,
 None
}

on GraphQL, it would look something like this;

option {
 Some 
 option
}

where Some is for the value of Some if that is the variant, and "option" for the option of the enum, so either Some or None.

In an enum like this

enum Direction {
    Left: 1,
    Right: 2,
    Up: 3,
    Down: 4,
}

It is not considered as a complex enum as it cannot store values in itself so we only return the variant name directly, so its only direction in GraphQL. For now, it has to be for the client to also hard code those values.

But I do understand the benefit of directly returning those values directly from graphql so maybe it is something to consider for GraphQL. Where we could get the value of an enum variant like this

direction {
 option
 value
}
rsodre commented 2 months ago

ok, good to know! I will adapt my clients to expect strings.

Graphql was used as an easy-to-replicate example, but I guess the enum return type for Torii GRPC should be the same, correct?

Larkooo commented 2 months ago

ok, good to know! I will adapt my clients to expect strings.

Graphql was used as an easy-to-replicate example, but I guess the enum return type for Torii GRPC should be the same, correct?

GRPC is a bit different as it uses "native" types. It uses Ty whcih englobes all of the possible types. You can look at the protobuf of the grpc server to get a better idea of it.

ScottyDavies commented 1 month ago

Hello @rsodre please can i work on this?

rsodre commented 1 month ago

torii is working as designed. closing this...