How to create Dev Protocol Dapp (2/3)

Kawakami
所要時間, 12分
初級

はじめに permalink

みなさん、こんにちわ
Dev Protocolで用意されているライブラリを使って、3回に分けて簡単なDappを作成したいと思います。
今回は2回目の記事になります。前回をまだ見ていない場合は1回目に戻って進めてみてください。

今回はクリエイターの詳細画面を作っていきたいと思います

開発環境の用意 permalink

開発環境は1回目で使用したものを引き続き使っていきます。詳しくは1回目をご確認ください

今回作成するページについて permalink

今回作成するページは、前回作成したクリエイター一覧ページから遷移される、クリエイターの詳細ページになります。クリエイターの詳細ページでは、クリエイターの情報と所持しているトークンの表示を行います。

tokens page

STEP01: クリエイター情報の取得 permalink

クリエイター情報は、dev-for-appsより取得します(前回と方法は同じです)取得するために使うクリエイターのアドレスは、indexページからのリンクURLに付加されています

/**
* indexから以下のURLでページ遷移されてくる
* https://localhost:3000/tokens.html?creator=xxxxx
**/

const urlParams = new URLSearchParams(window.location.search);
const creator = urlParams.get('creator')

const query_params = new URLSearchParams({
address: creator,
});

const response = await fetch("https://dev-for-apps.azureedge.net/accounts?" + query_params, {
method: "GET"
});

...

STEP02: トークン情報の取得 permalink

トークン情報は、Data Viewerから取得します。前回と同じ方法ですが、クリエイターのアドレスでフィルタリングして取得します。前回と取得したい情報が違うのでクエリも変更しています

const response = await fetch("https://api.devprotocol.xyz/v1/graphql", {
method: "POST",
headers: {
"X-Requested-With": "xhr",
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
query Properties {
property_meta(where: {author: {_eq: "
${address}"}}) {
property
author
name
}
}
`
,
}),
});

STEP03: トークンのカバー画像の取得 permalink

Data Viewerでは、トークンのカバー画像は取得できないためdev-for-appから取得します。前回のクリエイター情報の取得の時とはエンドポイントが変わります

const query_params = new URLSearchParams({
address: address,
});

const response = await fetch("https://dev-for-apps.azureedge.net/properties?" + query_params, {
method: "GET"
});

習得したデータは以下のようなJSON形式になっています。

[
{
"cover_image": {
"url": "https://storageaccountdevfobc15.blob.core.windows.net/dev-for-apps-images/assets/d3e6c900_6a1b_11ea_91be_d87dfda8b8e7_36d483d5b7.jpg",
...
},
...
}
]

これ以外にもさまざまな情報が取得できますが、ここでは詳細ページで使用するもの以外は省略しております。

STEP04: 詳細ページをコーディングする permalink

それでは詳細ページをコーディングしていきましょう。以下のコードを参考にmain.tsをコーディングしてください

window.addEventListener("load", async () => {
/**
* main.tsは、一覧ページと詳細ページの両方から呼ばれるので
* それぞれで処理を分けるため処理を追加する
*/


// 注意)1回目で作成した一覧ページの処理はこのif文の中に移動する
if (document.getElementById("page-index")) {

}

// 詳細ページの処理はここから記載する
if (document.getElementById("page-tokens")) {
// URLのGETパラメーターからクリエイターのアドレスを取得する
const urlParams = new URLSearchParams(window.location.search);
const creatorAddress = urlParams.get('creator');

// dev-for-appを使用してクリエイター情報を取得する
const creatorInfo = await getCreatorInfo(creatorAddress);

// クリエイター情報を表示するHTMLの作成
const profileElementString = `
<img class="mb-4 rounded-circle border border-3 border-dark" src="
${creatorInfo.portrait.url}" alt="creator image" width="168" height="168" style="object-fit: contain">
<p class="mb-0 fs-5">
${creatorInfo.name}</p>
`


const creatorHTMLElement = document.getElementById("creator");
creatorHTMLElement.innerHTML = profileElementString;

// トークン情報を表示させるHTMLを取得する
const tokensHTMLElement = document.getElementById("tokens");

// Data Viewerからトークン一覧を取得してくる
for (const token of await getTokens(creatorAddress)) {
// トークンの画像を取得します
const tokenInfo = await getPropertiesInfo(token.property)

if (!tokenInfo) {
continue
}

const image = tokenInfo.cover_image ? tokenInfo.cover_image.url : ""

// トークン情報を表示するHTMLの作成
const div = document.createElement('div');

div.innerHTML = `
<article class="mt-4 mb-3 d-flex">
<img class="me-3" src="
${image}" alt="token image" width="128" height="96" style="object-fit: contain">
<div class="d-flex flex-column justify-content-between">
<p class="fs-6">
${token.name}</p>
<div class="d-flex">
<button type="button" class="me-3 btn btn-lg btn-primary" address="
${token.property}" amount="1">1 DEV</button>
<button type="button" class="me-3 btn btn-lg btn-success" address="
${token.property}" amount="5">5 DEV</button>
<button type="button" class="btn btn-lg btn-danger" address="
${token.property}" amount="10">10 DEV</button>
</div>
</div>
</article>
`
;

const tokenHTMLElement = div.firstElementChild;

// 追加します
tokensHTMLElement.appendChild(tokenHTMLElement)
}
}
});

ここからのコードは上記のコードの下に追記するか、別ファイルを用意してImportする形でもよいです

async function getPropertiesInfo(address) {
const query_params = new URLSearchParams({
address: address,
});

const response = await fetch("https://dev-for-apps.azureedge.net/properties?" + query_params, {
method: "GET"
});

const info = await response.json();

if (!info[0]) {
return
}

return info[0];
}
async function getTokens(creator) {
const response = await fetch("https://api.devprotocol.xyz/v1/graphql", {
method: "POST",
headers: {
"X-Requested-With": "xhr",
"Content-Type": "application/json",
},
body: JSON.stringify({
query: `
query Properties {
property_meta(where: {author: {_eq: "
${creator}"}}) {
property
author
name
}
}
`
,
}),
});
const json = await response.json();

return json.data.property_meta;
}

ここまでのコーディングと、少しの修正を加えると以下のようなページが完成します

tokens page

このソースコードは下記より確認することができます

https://github.com/kazu80/tokener-find/tree/master/src

まとめ permalink

今回はData Viewerからクリエイターが所持しているトークン情報を取得して、そのトークンの画像をdev-for-appから取得して詳細ページを作りました。Data Viewerとdev-for-appの使い方にも慣れてきたのではないでしょうか。

次回はトークンにステーキングする処理と、自分のWalletとの接続を作成していきたいと思います

🌈 この記事はお役に立ちましたか?

今後より良いコンテンツをお届けしていくために、ぜひご質問やフィードバックなどいただけると幸いです🌱
フォーラムはこちら

- Dev Protocol は全てOSSとして公開しています。ぜひIssueやPRを送ってください📢 時にバウンティがあります。
Dev ProtocolのGitHubはこちら

- Dev Protocol の改善提案(DIP)プロセスも公開されています。ぜひコメントをお待ちしています🌟
DIPはこちら