Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ToJSON instances for IntN, UintN and generated datatypes #136

Merged
merged 2 commits into from
Sep 30, 2022

Conversation

RubenAstudillo
Copy link
Contributor

@RubenAstudillo RubenAstudillo commented Sep 28, 2022

Motivation

From the Network.Ethereum.Contract.TH module we can generate native ADTs to events specified on a contract ABIs. This is great if the rest of you project uses exclusively Haskell, but if you need to play along another languages or ecosystems, having a common representation such a JSON is necessary. This PR adds ToJSON instances for all events types (not internal Data$ nor Indexed$ ADTs though).

Changes

  • Add missing ToJSON instances for UintN and IntN.
  • Add aeson-casing dependency
  • Add ToJSON instances for generated datatypes using Generic deriving (aeson default).

Known infelicities

The init' function I use to recover the input name from the record selector of an ADT is a hack. The correct way should be to obtain that name from the eveArgName field on the inputs. But if I follow path, I would have to write custom code for instance generation, losing the benefits of using the Generic instance. It is a tradeoff and I choose succinctness.

Tests

I have been using this for 1 month, storing the JSONs produced on a postgresql database. So far the output matches what I would expect.

For a event declared like this

  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "tokenId",
        "type": "uint256"
      }
    ],
    "name": "Transfer",
    "type": "event"
  },

We generate the following instance

ghci> toJSON (Transfer def def 1000)
Object (fromList [("from",String "0x0000000000000000000000000000000000000000"),("to",String "0x0000000000000000000000000000000000000000"),("tokenId",Number 1000.0)])

On anohter event with arguments prefixed by _

  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "name": "_bidder",
        "type": "address"
      },
      {
        "indexed": true,
        "name": "_editionNumber",
        "type": "uint256"
      },
      {
        "indexed": true,
        "name": "_tokenId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "name": "_amount",
        "type": "uint256"
      }
    ],
    "name": "BidAccepted",
    "type": "event"
  },

The json instance is

ghci> toJSON (BidAccepted def 100 100 150)
Object (fromList [("_amount",Number 150.0),("_bidder",String "0x0000000000000000000000000000000000000000"),("_editionNumber",Number 100.0),("_tokenId",Number 100.0)])

License

Copyright belongs to SuperRare Labs. It is licensed under the Apache 2.0 terms as the rest of this project. If another license is needed with more liberal terms we can accommodate that. Thank you for all your work on this library!

@RubenAstudillo RubenAstudillo changed the title Add To-JSON instances for IntN, UintN and generated datatypes Add ToJSON instances for IntN, UintN and generated datatypes Sep 28, 2022
Copy link
Member

@akru akru left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing, thank you!

@akru akru merged commit 60db7fc into airalab:master Sep 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants