MỚI: Helius mua lại Light Protocol
cách sử dụng DAS API để trả về tất cả tài sản trong một bộ sưu tập
Blog/Phát triển

Solana Dev 101 - Sử dụng DAS API để truy xuất tất cả NFT trong một bộ sưu tập

Trưởng bộ phận Quan hệ Nhà phát triểnHunter Davis trên LinkedIn
Đọc trong 6 phút

Tổng quan

Digital Asset Standard (DAS) API là một giao diện mới ra mắt, hợp nhất tài sản thông thường và tài sản nén trên Solana (token, NFT, v.v.). Với sự xuất hiện của tài sản nén, các nhà phát triển Solana giờ đây có thể truy xuất mọi tài sản liên kết với một ví, bộ sưu tập hoặc authority hiệu quả hơn mà không cần sử dụng nhiều endpoint. DAS API cũng được lập chỉ mục ở phía sau, mang lại các lệnh gọi có hiệu suất cao nhất cho nhà phát triển. Với DAS, bạn có thể tinh giản quy trình truy xuất thông tin bằng cách loại bỏ các lệnh gọi gPA kéo dài. Trong endpoint getAssetsByOwner, bạn có thể truy cập metadata và thông tin off-chain của tất cả tài sản thuộc một bộ sưu tập cụ thể bằng ID bộ sưu tập on-chain của bộ sưu tập đó.

Trong hướng dẫn này, chúng ta sẽ trình bày cách sử dụng DAS API để truy xuất thông tin tài sản từ bộ sưu tập Mad Lads. Để làm theo với codebase hiện tại, bạn có thể xem kho lưu trữ GitHub tại đây.  Bạn cũng có thể tham khảo tài liệu DAS API toàn diện của chúng tôi để biết thêm thông tin.

Điều kiện tiên quyết

  • Đã cài đặt Node.js (v18.0 trở lên để sử dụng fetch tích hợp sẵn).
  • Có hiểu biết cơ bản về JavaScript.

Thiết lập môi trường

  1. Tạo một thư mục cho dự án này với tên collection.
  2. Trong thư mục collection, tạo một tệp có tên assetList.js. Chúng ta sẽ viết hàm trong tệp này.
  3. Tạo API Key tại Developer Portal của chúng tôi. Chuyển đến RPCs và sao chép liên kết Mainnet RPC. Liên kết này sẽ được dùng làm biến URL trong hướng dẫn.
  4. Lấy Certified Collection ID của một bộ sưu tập mẫu để kiểm thử. Trong trường hợp này, chúng ta sẽ dùng Mad Lads, có ID bộ sưu tập là J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w. Bạn có thể tìm địa chỉ bộ sưu tập on-chain trên một marketplace như Magic Eden khi xem một NFT cụ thể.

Các bước thực hiện

Sau đây là cách sử dụng DAS API để truy xuất thông tin tài sản từ một bộ sưu tập NFT.

1. Tạo hàm getAssetsByGroup

Trước tiên, hãy tạo một hàm để truy xuất tất cả tài sản liên quan đến một bộ sưu tập. Chúng ta sẽ lồng yêu cầu POST gửi đến DAS API bên trong hàm này.

Bắt đầu bằng cách thiết lập một hàm bất đồng bộ:

Mã
const { promises : fs } = require("fs");
const url = `https://rpc.helius.xyz/?api-key=`;

const getAssetsByGroup = async () => {
// Code goes here.
};

getAssetsByGroup();

Trong phần này, chúng ta đã import mô-đun fs để xử lý các thao tác trên hệ thống tệp, xác định RPC URL và khai báo hàm getAssetsByGroup.

Hãy nhớ thay <api-key> bằng API Key của bạn từ Developer Portal.

2. Tạo yêu cầu POST đến DAS

Hãy định nghĩa hàm getAssetsByGroup, đồng thời chỉ định trang bắt đầu và các tham số trả về của yêu cầu. Chúng ta sẽ dùng hàm fetch để tuân theo tài liệu về phương thức.

Mã
console.time('getAssetsByGroup');
let page = 1;
let assetList = [];

Chúng ta bắt đầu bộ đếm thời gian bằng console.time('getAssetsByGroup'), sau đó khởi tạo các biến cho trang hiện tại và một mảng trống để lưu các tài sản đã truy xuất.

Chúng ta dùng fetch cùng await để gửi một yêu cầu POST bất đồng bộ đến endpoint url được chỉ định:

Mã
try {
   while (page) {
    const response = await fetch(url, {
      method: 'POST',

Tiếp theo, chúng ta bước vào một vòng lặp while. Vòng lặp này sẽ tiếp tục truy xuất dữ liệu từ API miễn là biến page chưa có giá trị false.

Sau đó, chúng ta dùng fetch cùng await. Đây là một thao tác bất đồng bộ dùng để gửi yêu cầu HTTP. Chúng ta chỉ định url của endpoint API và đặt phương thức thành 'POST'. Điều này có nghĩa là dữ liệu được gửi đến máy chủ trong phần body của yêu cầu.

Mã
headers: {
	'Content-Type': 'application/json',
},

Trong phần header của yêu cầu, chúng ta đặt 'Content-Type' thành 'application/json'. Thiết lập này cho máy chủ biết rằng chúng ta đang gửi dữ liệu JSON.

Mã
body: JSON.stringify({
	jsonrpc: '2.0',
	id: 'my-id',
	method: 'getAssetsByGroup',
	params: {
		groupKey: 'collection',
		groupValue: 'J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w',
		page: page,
		limit: 1000,
	},
}),

Tiếp theo, chúng ta cấu hình body của yêu cầu dưới dạng một đối tượng JSON và chuyển đối tượng này thành chuỗi theo định dạng có thể gửi đến endpoint. Tại đây, chúng ta định nghĩa groupKey (sẽ là “collection”) và groupValue (sẽ đại diện cho ID bộ sưu tập on-chain).

Mã
if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }

const { result } = await response.json();

Bây giờ, chúng ta thiết lập cơ chế phát sinh lỗi nếu phản hồi từ máy chủ không thành công. Nếu yêu cầu thành công, phản hồi sẽ được hiển thị ở định dạng JSON.

Bạn có thể gặp lỗi nếu chưa đặt API key hợp lệ trong url.

3. Thêm tài sản mới vào danh sách

Trong phần trước, ban đầu chúng ta đã thiết lập getAssetsByGroup chạy khi trang được đặt thành 1. Tuy nhiên, hàm này chưa được cấu hình để duyệt qua mọi trang kết quả có thể có. Hãy thiết lập phần đó tiếp theo:

Mã
assetList.push(...result.items);
    if (result.total !== 1000) {
      page = false;
    } else {
      page++;
    }
  }

Đoạn code này thêm các mục từ phản hồi vào mảng assetList. Nếu tổng số kết quả không bằng giới hạn 1.000, chúng ta đặt page thành false để thoát khỏi vòng lặp.

4. Ghi tài sản vào tệp

Để lưu thông tin tài sản đã truy xuất vào một tệp JSON bên ngoài, hãy thêm đoạn code sau:

Mã
const resultData = {
    totalResults: assetList.length,
    results: assetList,
  };

  await fs.writeFile('results.json', JSON.stringify(resultData, null, 2));
	console.log('Results saved to results.json')
  console.timeEnd('getAssetsByGroup');

Đoạn code này tạo một đối tượng resultData gồm tổng số kết quả và mảng assetList. Chúng ta dùng fs.writeFile để ghi dữ liệu vào tệp JSON có tên results.json. Cuối cùng, chúng ta ghi một thông báo xác nhận vào log và kết thúc bộ đếm thời gian bằng console.timeEnd.

5. Triển khai xử lý lỗi

Bây giờ, chúng ta cần thiết kế một cơ chế dự phòng để xử lý các trường hợp yêu cầu đến máy chủ thất bại. Có thể thực hiện việc này bằng thiết lập sau. Khối code này sẽ ghi thông báo lỗi vào bảng điều khiển nếu có vấn đề xảy ra trong quá trình thực thi yêu cầu.

Mã
} catch (error) {
    console.error('Error occurred:', error);
}

Bạn có thể gặp lỗi khi gửi yêu cầu nếu không cung cấp ID bộ sưu tập on-chain hợp lệ.

Code hoàn chỉnh

Tệp assetList.js của bạn sẽ tương tự đoạn code sau.

Mã
const { promises : fs } = require("fs");
const url = `https://rpc.helius.xyz/?api-key=`;

const getAssetsByGroup = async () => {
  console.time('getAssetsByGroup'); // Start the timer
  let page = 1;
  let assetList = [];

try {
   while (page) {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 'my-id',
        method: 'getAssetsByGroup',
        params: {
          groupKey: 'collection',
          groupValue: 'J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w',
          page: page,
          limit: 1000,
        },
      }),
    });
		if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
    }
    const { result } = await response.json();

    assetList.push(...result.items);
    if (result.total !== 1000) {
      page = false;
    } else {
      page++;
    }
  }

  const resultData = {
    totalResults: assetList.length,
    results: assetList,
  };

  await fs.writeFile('results.json', JSON.stringify(resultData, null, 2));
	console.log('Results saved to results.json')
  console.timeEnd('getAssetsByGroup');

	} catch (error) {
    console.error('Error occurred:', error);
  }

};

getAssetsByGroup();

Kết quả

Khi tệp đã giống với đoạn code ở trên, bạn có thể chạy tệp bằng lệnh node assetList.js trong terminal để bắt đầu yêu cầu. Thao tác này sẽ tạo một tệp results.json.

Sau khi hoàn tất, bảng điều khiển sẽ cho biết kết quả đã được lưu vào tệp results.json và ghi lại thời gian truy xuất tài sản. Trong trường hợp của chúng tôi, khi dùng Node.js để truy xuất thông tin tài sản của bộ sưu tập on-chain Mad Lads, quy trình mất trung bình 9,27 giây.

Khi mở tệp results.json, bạn sẽ thấy tổng số kết quả được trả về cùng thông tin chi tiết về tài sản. Đây là các NFT riêng lẻ thuộc bộ sưu tập mà bạn đã truy vấn.

Để tùy chỉnh thêm dữ liệu trả về, bạn có thể trích xuất thông tin cụ thể như hình ảnh, chủ sở hữu và các metadata có giá trị khác.

results.json

Mã
{
  "totalResults": 9967,
  "results": [
    {
      "interface": "Custom",
      "id": "GVPX9rXRXo9SVGktJCzA3Qb9v263kQzEyAWsgX3LL8P5",
      "content": {
        "$schema": "https://schema.metaplex.com/nft1.0.json",
        "json_uri": "https://madlads.s3.us-west-2.amazonaws.com/json/859.json",
        "files": [
          {
            "uri": "https://madlads.s3.us-west-2.amazonaws.com/images/859.png",
            "cdn_uri": "https://cdn.helius.services/cdn-cgi/image//https://madlads.s3.us-west-2.amazonaws.com/images/859.png",
            "mime": "image/png"
          },
          {
            "uri": "https://arweave.net/qJ5B6fx5hEt4P7XbicbJQRyTcbyLaV-OQNA1KjzdqOQ/859.png",
            "cdn_uri": "https://cdn.helius.services/cdn-cgi/image//https://arweave.net/qJ5B6fx5hEt4P7XbicbJQRyTcbyLaV-OQNA1KjzdqOQ/859.png",
            "mime": "image/png"
          }
        ],
        "metadata": {
          "attributes": [
            {
              "value": "Male",
              "trait_type": "Gender"
            },
            {
              "value": "Galaxy",
              "trait_type": "Type"
            },
            {
              "value": "Galaxy",
              "trait_type": "Expression"
            },
            {
              "value": "Gambler",
              "trait_type": "Hat"
            },
            {
              "value": "Galaxy",
              "trait_type": "Eyes"
            },
            {
              "value": "Dark Windsor",
              "trait_type": "Clothing"
            },
            {
              "value": "Grey",
              "trait_type": "Background"
            }
          ],
          "description": "Fock it.",
          "name": "Mad Lads #859",
          "symbol": "MAD"
        },
        "links": {
          "external_url": null
        }
      },
      "authorities": [
        {
          "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW",
          "scopes": [
            "full"
          ]
        }
      ],
      "compression": {
        "eligible": false,
        "compressed": false,
        "data_hash": "",
        "creator_hash": "",
        "asset_hash": "",
        "tree": "",
        "seq": 0,
        "leaf_id": 0
      },
      "grouping": [
        {
          "group_key": "collection",
          "group_value": "J1S9H3QjnRtBbbuD4HjPV6RpRhwuk4zKbxsnCHuTgh9w"
        }
      ],
      "royalty": {
        "royalty_model": "creators",
        "target": null,
        "percent": 0.042,
        "basis_points": 420,
        "primary_sale_happened": true,
        "locked": false
      },
      "creators": [
        {
          "address": "5XvhfmRjwXkGp3jHGmaKpqeerNYjkuZZBYLVQYdeVcRv",
          "share": 0,
          "verified": true
        },
        {
          "address": "2RtGg6fsFiiF1EQzHqbd66AhW7R5bWeQGpTbv2UMkCdW",
          "share": 100,
          "verified": true
        }
      ],
      "ownership": {
        "frozen": false,
        "delegated": false,
        "delegate": null,
        "ownership_model": "single",
        "owner": "GX6KFMFS6yZGJzuZ28Q5Cbk9RN8Wv8UmNP2abcC4kcM2"
      },
      "supply": null,
      "mutable": true
    }, ...
    // Addtional Items
]

Phần này sẽ hiển thị toàn bộ tài sản được trả về. Giờ đây, bạn có thể thu hẹp dữ liệu hơn nữa để chỉ trả về địa chỉ token, chủ sở hữu và nhiều thông tin metadata khác.

Kết luận

Xin chúc mừng! Bạn đã truy xuất thành công tất cả tài sản của một bộ sưu tập gồm 10.000 mục bằng Digital Asset Standard (DAS) API mới ra mắt. Tóm lại:

  • DAS API cung cấp phương pháp truy xuất tài sản tinh gọn cho các dApp trên Solana.
  • Phương thức này hoạt động với cả bộ sưu tập thông thường và bộ sưu tập nén.
  • Bằng cách sử dụng DAS API, bạn có thể truy cập metadata và thông tin sở hữu trong chưa đến 15 giây.

Bằng cách sử dụng DAS API, chúng ta có thể tinh giản việc truy xuất tài sản cho các dApp trên Solana. Thay vì thực hiện nhiều lệnh gọi API để thu thập thông tin, chúng ta chỉ cần dùng một endpoint duy nhất.

Trong các hướng dẫn sắp tới, chúng ta sẽ tìm hiểu thêm một số phương án tinh gọn khác để truy xuất và tương tác với tài sản.

Hãy tham gia Discord của chúng tôi và đăng bất kỳ câu hỏi nào bạn có!

‍

Đăng ký nhận tin từ Helius

Luôn cập nhật những thông tin mới nhất về phát triển Solana và nhận thông báo khi chúng tôi đăng bài

Hình ảnh phóng to