0

I am trying to build a subgraph for Graph Protocol following the example here (the example with the more performant way). During compilation of my Graph protocol project using a testing tool matchstick-as ^0.5.0, I get the following error:

Igniting tests

nft-lottery
--------------------------------------------------
  Enter the NFT Lottery:
thread 'main' panicked at ' Unexpected error upon calling hook: Missing value for non-nullable field 'player' for an entity of type 'PlayerToLottery'.
wasm backtrace:
    0: 0x331a - <unknown>!src/nft-lottery/handleNftLotteryEnter;
    1: 0x3807 - <unknown>!start:tests/nft-lottery.test~anonymous|0~anonymous|0

Could anyone help me with this, please?

Here is my ./schema.graphql

type NftLottery @entity {
  id: ID!
  open: BigInt!
  close: BigInt!
  prize: BigInt!
  players: [PlayerToLottery!]! @derivedFrom(field: "lottery")
  requestId: BigInt
  updatedAtTimestamp: BigInt
}

type Player @entity {
  id: ID! # address
  lotteries: [PlayerToLottery!]! @derivedFrom(field: "player")
}

type PlayerToLottery @entity {
  id: ID! # Set playerAddress.toHexString() + lotteryId.toHexString()
  player: Player!
  lottery: NftLottery!
}

# events
type NftLotteryEnter @entity {
  id: ID! # Set lotteryCounter + playerAddress
  lotteryCounter: BigInt!
  player: Bytes!
  numberOfEntrances: [BigInt!]!
  updatedAtTimestamp: BigInt
}

Here is my ./src/mapping.ts

function getIdFromEventAddressInt(par2: Address, par1: BigInt): string {
  return par1.toHexString() + par2.toHexString()
}

export function handleNftLotteryEnter(event: NftLotteryEnterEvent): void {
  /* if a PlayerToLottery does not exists, create it */
  const playerLotteryId = getIdFromEventAddressInt(event.params.player, event.params.lotteryCounter)
  let playerToLottery = PlayerToLottery.load(playerLotteryId)
  if (!playerToLottery) {
      playerToLottery = new PlayerToLottery(playerLotteryId)
      playerToLottery.save()
    }

  /* if a player does not exist, create them */
  const playerId = event.params.player.toHexString()
  let player = Player.load(playerId)
  if (!player) {
    player = new Player(playerId)
    player.save()
  }

  /* if a lottery does not exist, create it */ 
  const itemId = event.params.lotteryCounter.toHexString()
  let nftLottery = NftLottery.load(itemId)
  if (!nftLottery) {
    nftLottery = new NftLottery(itemId)
    nftLottery.open = event.block.timestamp
    nftLottery.close = BigInt.fromString("000000000000")
    nftLottery.prize = BigInt.fromString(event.params.entranceFee.toString())
    nftLottery.players = new Array<string>()
  }
  // update lottery data
  nftLottery.prize.plus(event.params.entranceFee)
  // update players
  let arrPlayers = nftLottery.players
  arrPlayers.push(event.params.player.toHexString())
  nftLottery.players = arrPlayers

  nftLottery.updatedAtTimestamp = event.block.timestamp
  nftLottery.save()
}

haraslub
  • 151
  • 1
  • 10

1 Answers1

1

Entity PlayerToLottery needs to have values assigned before saving it:

/* if a PlayerToLottery does not exists, create it */
  const playerLotteryId = getIdFromEventAddressInt(event.params.player, event.params.lotteryCounter)
  let playerToLottery = PlayerToLottery.load(playerLotteryId)
  if (!playerToLottery) {
      playerToLottery = new PlayerToLottery(playerLotteryId)
      playerToLottery.player = event.params.player.toHexString()
      playerToLottery.lottery = event.params.lotteryCounter.toHexString()
      playerToLottery.save()
  }

Credit goes to Maks#3349 at unit testing of Graph discord.

haraslub
  • 151
  • 1
  • 10