Skip to main content
ArcBlock Community

Issue Fetching NFT Data from DID Explorer API

Twelve
Developers
hackathon-supportfeature

I’m currently working on fetching NFT data using the DID Explorer API. Specifically, I’m using the DID did:abt:zjdfNpWudcV9ZL8mA5g5Tp1fTPWUZAsGMQMw, but when I make the API call, the response is returning HTML instead of JSON.

I’m expecting the API to return the assets or NFTs associated with the DID, but it seems like the response is either incorrect or the data is not available. Could you please confirm if this DID has associated assets, or if there are any known issues with the API?

Any guidance would be appreciated.

13 replies

wangshijun1 year ago

How did you call the API? The ArcBlock Chain exposes a GraphQL endpoint for developers to query data and send transactions, and we have a dedicated client library for that, check out the following code snippet for how to query NFT State:

javascriptCopy
const Client = require('@ocap/client');

const endpoint = process.env.OCAP_API_HOST || 'https://main.abtnetwork.io/api';
const client = new Client(endpoint);

async function getAssetInfo(assetAddress) {
  try {
    const { state } = await client.getAssetState({ address: assetAddress });
    console.log('Asset State:', state);
  } catch (error) {
    console.error('Error fetching asset state:', error);
  }
}

// Usage
(async () => {
  // Assume assetAddress is defined earlier in your code
  await getAssetInfo(assetAddress);
})();

A few site nodes:

  • Please remember to add @ocap/client as dependency to your project
  • You can change the endpoint on L3 to https://beta.abtnetwork.io/api/ if your NFT is on test chain
wangshijun1 year ago
Twelve1 year ago

Initially, I tried calling the API directly from the frontend using a standard fetch request in my React component. Here's an example of how I made the API call:

javascriptCopy
jsCopy codeconst fetchNFTData = async (did) => {
  try {
    const response = await fetch(`https://main.abtnetwork.io/api/did/${did}`);
    if (!response.ok) {
      throw new Error('Failed to fetch NFT data');
    }
    const data = await response.json();
    console.log('NFT Data:', data);
    return data;
  } catch (error) {
    console.error('Error fetching NFT data:', error);
  }
};

However, I encountered issues like receiving HTML instead of JSON, which I believe might be related to CORS restrictions or other limitations.

I see now that you recommend using @ocap/client, which requires setting up a Node.js backend to handle these requests. Since I'm building a custom component in the Pages Kit, I was trying to avoid adding a backend setup for simplicity.

Do you have any suggestions for how I might be able to make this work without setting up a separate backend, or is the backend approach the only viable option with the current API setup?

Thanks for your help!

Twelve1 year ago

The custom component I’m building in the Pages Kit is designed so that users can easily enter their DID and display their NFT collection of choice. My goal is to keep the process simple by avoiding a backend setup, allowing users to manage and showcase their collections directly through the frontend.

wangshijun1 year ago(edited)

If you are using the API in Pages Kit, you should consider using the following code snippet:

javascriptCopy
const address = 'zjdejQDAtNaLegKkR4p1mFdzZHnGZwYesau3';
const query = `
  query {
    getAssetState(address: "${address}") {
      state {
        address
        owner
        moniker
        readonly
        transferrable
        ttl
        consumedTime
        issuer
        parent
        tags
        data {
          typeUrl
          value
        }
        display {
          type
          content
        }
        context {
          genesisTime
          renaissanceTime
        }
      }
    }
  }
`;

const endpoint = 'https://main.abtnetwork.io/api'; // Replace with your actual GraphQL endpoint

fetch(endpoint, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
  },
  body: JSON.stringify({ query })
})
  .then(response => response.json())
  .then(data => {
    console.log('Asset State:', data.data.getAssetState);
  })
  .catch(error => {
    console.error('Error:', error);
  });
Twelve1 year ago

In the code snippet you provided, I see the placeholder endpoint https://main.abtnetwork.io/developer/api. and I also see Replace with your actual GraphQL endpoint.

Could you please provide the actual GraphQL endpoint for querying asset states or NFT data? I’m currently getting a 404 error.

or am i just totally doing this wrong 🙂

Twelve1 year ago

athis is the code im using in the custom component area. I don't know why it is having api issue.

javascriptCopy
import React, { useState } from '@blocklet/pages-kit/builtin/react';
import { Box, TextField, Button, Typography } from '@blocklet/pages-kit/builtin/mui/material';

export default function DIDInfoComponent() {
  const [did, setDid] = useState('');
  const [nftData, setNftData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const fetchNFTData = async () => {
    setLoading(true);
    setError(null);

    const query = `
      query {
        getAssetState(address: "${did}") {
          state {
            address
            owner
            moniker
            readonly
            transferrable
            ttl
            consumedTime
            issuer
            parent
            tags
            data {
              typeUrl
              value
            }
            display {
              type
              content
            }
            context {
              genesisTime
              renaissanceTime
            }
          }
        }
      }
    `;

    const endpoint = 'https://main.abtnetwork.io/developer/api';

    try {
      const response = await fetch(endpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json',
        },
        body: JSON.stringify({ query }),
      });

      const result = await response.json();
      setNftData(result.data.getAssetState.state);
    } catch (err) {
      setError('Failed to fetch NFT data');
    } finally {
      setLoading(false);
    }
  };

  return (
    <Box>
      <Typography variant="h5">Enter Your DID</Typography>
      <TextField
        label="DID"
        value={did}
        onChange={(e) => setDid(e.target.value)}
        fullWidth
        margin="normal"
      />
      <Button variant="contained" color="primary" onClick={fetchNFTData} disabled={!did || loading}>
        {loading ? 'Loading...' : 'Fetch NFT Data'}
      </Button>

      {error && <Typography color="error">{error}</Typography>}

      {nftData && (
        <Box mt={2}>
          <Typography>Owner: {nftData.owner}</Typography>
          <Typography>Moniker: {nftData.moniker || 'Unnamed Asset'}</Typography>
          {/* Add other data fields as needed */}
        </Box>
      )}
    </Box>
  );
}
``
wangshijun1 year ago

Removing the /developer part should fix the issue

Twelve1 year ago

thank you!

Twelve1 year ago

thank you we got it!

Twelve1 year ago

Thank you for all your help.

I will continue to fine tune the component, but it is now working.

This custom component for pages kit has props for title, backround image and opacity, column qty, and for DIDs to be entered in order create card holders.

I think this will be tremendously helpful for people who want to have a way to quickly show of their collections.

Here is an example of the the gallery

The Daily Arc

wangshijun1 year ago

Perhaps you can publish this component as a blocklet to Blocklet Store, so that others can reuse it, 😄

Twelve1 year ago

Certainly.

Reply