The Graph:如何在我的响应中包含这个存在于不同 GraphQL 类型中的 "price" 值?

The Graph: How can I include in my response this "price" value that exists in a different GraphQL type?

我正在使用 thegraph.com 并创建了一个子图来索引来自我从头开始构建的 NFT 市场智能合约的区块链数据,仅用于我自己的教育目的。同时,我第一次在这里使用 GraphQL 和构建查询,所以我什至不确定这是否是正确的问题,但我会通过下面的截图来说明我的最终目标是什么. 这是我正在使用的子图端点,以防有人想检查我在那里的模式并使用它:https://api.thegraph.com/subgraphs/name/parenthesislab/cubansea-mumbai-v9/graphql

我想要的结果:接收存在于 MarketTokenMinted 中的这个 price 值,在我正在处理的相应 ERC721tokens 对象中键入这个 API 回复。

我当前的 GraphQL 查询(根据上面的屏幕截图生成响应 ^):

query FetchMarketTokens {
  account(id: "0xae198b77c760c8d547f796f57c469c0294592ab8") {
    id
    ERC721tokens(orderBy: identifier, orderDirection: desc, first: 10) {
      id
      identifier
      uri
    }
  }
  marketTokenMinteds(orderBy: tokenId, orderDirection: desc) {
    nftContract
    price
    tokenId
  }
}

我当前的 GraphQL 架构已部署到 The Graphsubgraph:

# schema.graphql

type MarketTokenMinted @entity {
  id: ID!
  itemId: BigInt! # uint256
  nftContract: Bytes! # address
  tokenId: BigInt! # uint256
  seller: Bytes! # address
  owner: Bytes! # address
  price: BigInt! # uint256
  sold: Boolean! # bool
}

type MarketTokenSold @entity {
  id: ID!
  itemId: BigInt! # uint256
  nftContract: Bytes! # address
  tokenId: BigInt! # uint256
  seller: Bytes! # address
  owner: Bytes! # address
  price: BigInt! # uint256
  sold: Boolean! # bool
}

type Account @entity {
    id: ID!
    asERC721: ERC721Contract
    ERC721tokens: [ERC721Token!]! @derivedFrom(field: "owner")
    ERC721operatorOwner: [ERC721Operator!]! @derivedFrom(field: "owner")
    ERC721operatorOperator: [ERC721Operator!]! @derivedFrom(field: "operator")
    ERC721transferFromEvent: [ERC721Transfer!]! @derivedFrom(field: "from")
    ERC721transferToEvent: [ERC721Transfer!]! @derivedFrom(field: "to")
    events: [Event!]! @derivedFrom(field: "emitter")
}
type ERC721Contract @entity {
    id: ID!
    asAccount: Account!
    supportsMetadata: Boolean
    name: String
    symbol: String
    tokens: [ERC721Token!]! @derivedFrom(field: "contract")
    operators: [ERC721Operator!]! @derivedFrom(field: "contract")
    transfers: [ERC721Transfer!]! @derivedFrom(field: "contract")
}
type ERC721Token @entity {
    id: ID!
    contract: ERC721Contract!
    identifier: BigInt!
    owner: Account!
    approval: Account!
    uri: String
    transfers: [ERC721Transfer!]! @derivedFrom(field: "token")
}
type ERC721Operator @entity {
    id: ID!
    contract: ERC721Contract!
    owner: Account!
    operator: Account!
    approved: Boolean!
}
type ERC721Transfer implements Event @entity {
    id: ID!
    emitter: Account!
    transaction: Transaction!
    timestamp: BigInt!
    contract: ERC721Contract!
    token: ERC721Token!
    from: Account!
    to: Account!
}
interface Event {
    id: ID!
    transaction: Transaction!
    emitter: Account!
    timestamp: BigInt!
}
type Transaction @entity {
    id: ID!
    timestamp: BigInt!
    blockNumber: BigInt!
    events: [Event!]! @derivedFrom(field: "transaction")
}

经过无数小时的尝试,我不再确定我遗漏了什么或如何将其组合在一起以接收此 price 值以及每个 [ 上获得的其余数据=15=] 对象收到。非常感谢任何帮助我朝着正确方向前进的帮助。

终于找到方法了,在这里回答我自己的问题以供将来参考。

这可以通过将 price 字段添加到我的架构的 ERC721Token 实体中来完成。然后我能够将映射逻辑添加到事件返回价格中,这将加载 ERC721Token 实体并在那里保存价格信息。此事件是 MarketTokenMinted

最终的解决方案汇总如下:

添加了可选价格字段的 ERC721Token 类型:

type ERC721Token @entity {
  id: ID!
  contract: ERC721Contract!
  identifier: BigInt!
  owner: Account!
  approval: Account!
  uri: String
  transfers: [ERC721Transfer!]! @derivedFrom(field: "token")
  price: BigInt # uint256
}

mapping.ts 文件添加了映射逻辑以通过 tokenId 参数(来自 MarketTokenMintedEvent)获取令牌,添加 .price 属性和值并保存 token.save():

import {
  MarketTokenMinted as MarketTokenMintedEvent,
  MarketTokenSold as MarketTokenSoldEvent,
} from "../generated/CSMarket/CSMarket";
import { MarketTokenMinted, MarketTokenSold } from "../generated/schema";
import { fetchERC721, fetchERC721Token } from "./fetch/erc721";

export function handleMarketTokenMinted(event: MarketTokenMintedEvent): void {
  let entity = new MarketTokenMinted(
    event.transaction.hash.toHex() + "-" + event.logIndex.toString()
  );
  entity.itemId = event.params.itemId;
  entity.nftContract = event.params.nftContract;
  entity.tokenId = event.params.tokenId;
  entity.seller = event.params.seller;
  entity.owner = event.params.owner;
  entity.price = event.params.price;
  entity.sold = event.params.sold;

  // Add token price value to new .price field in the ERC721Token type.
  let contract = fetchERC721(event.params.nftContract);
  if (contract != null) {
    let token = fetchERC721Token(contract, event.params.tokenId);

    token.price = event.params.price;

    contract.save();
    token.save();
  }

  entity.save();
}

FetchMarketTokensByOwner添加价格字段:

query FetchMarketTokensByOwner {
  erc721Tokens(
    where: {owner: "0xae198b77c760c8d547f796f57c469c0294592ab8"}
    orderBy: identifier
    orderDirection: desc
    first: 10
  ) {
    identifier
    uri
    owner {
      id
    }
    price
  }
}

我现在得到的结果是每个令牌对象中包含的 price 值:

{
  "data": {
    "erc721Tokens": [
      {
        "identifier": "4",
        "uri": "https://ipfs.infura.io/ipfs/QmfZXdugdU6BwtxWDNxpnETviB36qBX9qrLDrxeDSoFept",
        "owner": {
          "id": "0xae198b77c760c8d547f796f57c469c0294592ab8"
        },
        "price": "324324520000000"
      },
      {
        "identifier": "3",
        "uri": "https://ipfs.infura.io/ipfs/QmW21btPRbB8zgXiLs4oegpGXiLLSX9jnuSip4axwkFdaz",
        "owner": {
          "id": "0xae198b77c760c8d547f796f57c469c0294592ab8"
        },
        "price": "343235000000000"
      },
      {
        "identifier": "1",
        "uri": "https://ipfs.infura.io/ipfs/QmRKGJMnnLMBeT72bXU6yjG2g2MpHSvrq8pRGbZykmjSgE",
        "owner": {
          "id": "0xae198b77c760c8d547f796f57c469c0294592ab8"
        },
        "price": "323424523400000"
      }
    ]
  }
}