mcpField
H
hedera-token-service

hedera-token-service

github.com/hedera-dev開発28567 回インストール8 週間前に更新
リポジトリ

hedera-token-service について

hedera-token-serviceは、`@hiero-ledger/sdk`を使うHedera Token Service向けJavaScript SDKのスキルです。ファンジブルトークンとNFT、取引、クエリ、キー、コンプライアンス制御を扱います。

主な機能

  1. 01ファンジブルトークンとNFTの作成
  2. 02トークンのミント、バーン、転送
  3. 03アカウントとトークンの関連付け
  4. 04KYC、凍結、ワイプ、一時停止制御
  5. 05トークンとNFTの詳細照会
  6. 06カスタム手数料スケジュールの設定

活用シーン

  1. 01ファンジブルトークンやNFTコレクションの作成
  2. 02トークン発行と転送の管理
  3. 03アカウント単位のコンプライアンス制御
  4. 04トークン供給量やNFT情報の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/hedera-dev/hedera-skills --skill hedera-token-service

インストール後、Claude Code で/hedera-token-serviceを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evals/
evals.json
spec.json
references/
api-reference.md
custom-fees.md

詳細

Hedera Token Service (HTS) — JavaScript SDK

HTS は Hedera ネイティブのトークンエンジンです。スマートコントラクトを書かずに、代替性トークン(fungible token)や NFT を作成・管理できます。HTS を通じて作成されたトークンは、組み込みのコンプライアンス制御(KYC、フリーズ、ワイプ、一時停止)とカスタム手数料スケジュールを備えた、ファーストクラスのネットワークエンティティです。

セットアップ

すべてのインポートは @hiero-ledger/sdk から行います。セットアップのパターンは 2 つあります。

Client + setOperator(直接方式)
import { Client, AccountId, PrivateKey } from "@hiero-ledger/sdk";

const client = Client.forName(process.env.HEDERA_NETWORK)
    .setOperator(
        AccountId.fromString(process.env.OPERATOR_ID),
        PrivateKey.fromStringECDSA(process.env.OPERATOR_KEY),
    );
Wallet + LocalProvider(署名者ベース)
import { Wallet, LocalProvider } from "@hiero-ledger/sdk";

const provider = new LocalProvider();
const wallet = new Wallet(process.env.OPERATOR_ID, process.env.OPERATOR_KEY, provider);

署名者パターンでは、freezeWith(client) / execute(client) の代わりに、freezeWithSigner(wallet)、signWithSigner(wallet)、executeWithSigner(wallet)、getReceiptWithSigner(wallet) を使用します。

トランザクションのライフサイクル

すべてのトランザクションは次の流れに従います: configure -> freeze -> sign -> execute -> receipt。

const tx = await new SomeTransaction()
    .setSomeField(value)
    .freezeWith(client);   // locks the transaction body

await tx.sign(privateKey); // add signatures (call multiple times for multi-sig)

const response = await tx.execute(client);
const receipt = await response.getReceipt(client);

オペレーターキーのみが必要な場合は、明示的な freeze/sign を省略できます — execute(client) が処理します。

const response = await new SomeTransaction()
    .setSomeField(value)
    .execute(client);
const receipt = await response.getReceipt(client);

トークンの作成

代替性トークン(Fungible Token)
import {
    TokenCreateTransaction, TokenType, TokenSupplyType,
    PrivateKey, Hbar,
} from "@hiero-ledger/sdk";

const supplyKey = PrivateKey.generateECDSA();

const { tokenId } = await (
    await new TokenCreateTransaction()
        .setTokenName("My Token")
        .setTokenSymbol("MTK")
        .setDecimals(2)
        .setInitialSupply(10000)
        .setTreasuryAccountId(operatorId)
        .setAdminKey(operatorKey)
        .setSupplyKey(supplyKey)
        .execute(client)
).getReceipt(client);
NFT(非代替性トークン)

NFT には TokenType.NonFungibleUnique が必要です。NFT には小数桁がなく、初期供給量もありません — 作成後に個別のシリアルをミントします。

const { tokenId: nftId } = await (
    await new TokenCreateTransaction()
        .setTokenName("My NFT Collection")
        .setTokenSymbol("MNFT")
        .setTokenType(TokenType.NonFungibleUnique)
        .setSupplyType(TokenSupplyType.Finite)
        .setMaxSupply(1000)
        .setTreasuryAccountId(treasuryId)
        .setAdminKey(adminKey)
        .setSupplyKey(supplyKey)
        .execute(client)
).getReceipt(client);

ミント

import { TokenMintTransaction } from "@hiero-ledger/sdk";

// Fungible — specify amount
await new TokenMintTransaction()
    .setTokenId(tokenId)
    .setAmount(500)
    .execute(client);

// NFT — specify metadata per serial
const { serials } = await (
    await new TokenMintTransaction()
        .setTokenId(nftId)
        .addMetadata(Buffer.from("ipfs://QmFirst..."))
        .addMetadata(Buffer.from("ipfs://QmSecond..."))
        .execute(client)
).getReceipt(client);
// serials = [Long(1), Long(2)]

トークンの関連付け

Hedera アカウントは、トークンを受け取る前にそのトークンに関連付け(associate)する必要があります(アカウントで setMaxAutomaticTokenAssociations による自動トークン関連付けが有効になっている場合を除く)。

import { TokenAssociateTransaction } from "@hiero-ledger/sdk";

await (
    await (
        await new TokenAssociateTransaction()
            .setAccountId(recipientId)
            .setTokenIds([tokenId])
            .freezeWith(client)
    ).sign(recipientKey)      // account owner must sign
).execute(client);

代わりに、アカウント作成時に setMaxAutomaticTokenAssociations(-1) を設定すると、無制限の自動関連付けが可能になります。

送金

代替性トークンと NFT の両方に TransferTransaction を使用します。金額は符号付きです: 負の値はデビット、正の値はクレジットです。トークンごとに合計がゼロになる必要があります。

import { TransferTransaction } from "@hiero-ledger/sdk";

// Fungible transfer
await new TransferTransaction()
    .addTokenTransfer(tokenId, senderId, -100)
    .addTokenTransfer(tokenId, receiverId, 100)
    .execute(client);

// NFT transfer (tokenId, serial, sender, receiver)
await new TransferTransaction()
    .addNftTransfer(nftId, 1, senderId, receiverId)
    .execute(client);

// Mix Hbar + token transfers in one transaction
await new TransferTransaction()
    .addHbarTransfer(senderId, new Hbar(-5))
    .addHbarTransfer(receiverId, new Hbar(5))
    .addTokenTransfer(tokenId, senderId, -50)
    .addTokenTransfer(tokenId, receiverId, 50)
    .execute(client);

キーの役割

各キーは省略可能です。作成時に省略した場合、その機能は永続的に無効になります。

キー目的
adminKeyトークンの更新/削除、他のキーのローテーション
supplyKeyミントとバーン
freezeKeyこのトークンの送金に対するアカウントのフリーズ/フリーズ解除
kycKeyアカウントへの KYC ステータスの付与/取り消し
wipeKeyアカウントからのトークン残高のワイプ
pauseKeyすべてのトークン操作のグローバルな一時停止/再開
feeScheduleKeyカスタム手数料スケジュールの更新
metadataKeyトークンまたは NFT のメタデータの更新

コンプライアンス操作

// Grant KYC (required when token has kycKey)
await new TokenGrantKycTransaction()
    .setTokenId(tokenId).setAccountId(accountId).execute(client);

// Freeze an account
await new TokenFreezeTransaction()
    .setTokenId(tokenId).setAccountId(accountId).execute(client);

// Unfreeze
await new TokenUnfreezeTransaction()
    .setTokenId(tokenId).setAccountId(accountId).execute(client);

// Wipe tokens from an account
await new TokenWipeTransaction()
    .setTokenId(tokenId).setAccountId(accountId).setAmount(10).execute(client);

// Pause all transfers
await new TokenPauseTransaction().setTokenId(tokenId).execute(client);

// Unpause
await new TokenUnpauseTransaction().setTokenId(tokenId).execute(client);

バーンと削除

import { TokenBurnTransaction, TokenDeleteTransaction } from "@hiero-ledger/sdk";

// Burn fungible
await new TokenBurnTransaction()
    .setTokenId(tokenId).setAmount(100).execute(client);

// Burn NFT serials
await new TokenBurnTransaction()
    .setTokenId(nftId).setSerials([1, 2]).execute(client);

// Delete entire token (requires adminKey)
await new TokenDeleteTransaction()
    .setTokenId(tokenId).execute(client);

トークン情報の照会

import { TokenInfoQuery, TokenNftInfoQuery, NftId } from "@hiero-ledger/sdk";

const info = await new TokenInfoQuery().setTokenId(tokenId).execute(client);
console.log(info.name, info.symbol, info.totalSupply.toString());

const nftInfo = await new TokenNftInfoQuery()
    .setNftId(new NftId(nftId, 1))
    .execute(client);
console.log(nftInfo.accountId.toString()); // current owner

エアドロップ

エアドロップはトークンを複数の受信者に配布します。受信者が自動関連付けできない場合、エアドロップは保留中(pending)になり、請求(claim)する必要があります。

import {
    TokenAirdropTransaction, TokenClaimAirdropTransaction,
    TokenCancelAirdropTransaction, TokenRejectTransaction, NftId,
} from "@hiero-ledger/sdk";

// Send airdrop
const record = await (
    await (
        await new TokenAirdropTransaction()
            .addTokenTransfer(tokenId, treasuryId, -300)
            .addTokenTransfer(tokenId, recipient1, 100)
            .addTokenTransfer(tokenId, recipient2, 100)
            .addTokenTransfer(tokenId, recipient3, 100)
            .addNftTransfer(nftId, 1, treasuryId, recipient1)
            .freezeWith(client)
            .sign(treasuryKey)
    ).execute(client)
).getRecord(client);

// Check pending airdrops
const { newPendingAirdrops } = record;

// Recipient claims a pending airdrop
await (
    await new TokenClaimAirdropTransaction()
        .addPendingAirdropId(newPendingAirdrops[0].airdropId)
        .freezeWith(client)
        .sign(recipientKey)
).execute(client);

// Sender cancels a pending airdrop
await new TokenCancelAirdropTransaction()
    .addPendingAirdropId(newPendingAirdrops[1].airdropId)
    .execute(client);

// Recipient rejects tokens they already received
await (
    await new TokenRejectTransaction()
        .setOwnerId(recipientId)
        .addTokenId(tokenId)           // reject fungible
        .addNftId(new NftId(nftId, 1)) // reject NFT
        .freezeWith(client)
        .sign(recipientKey)
).execute(client);

カスタム手数料

HTS は 3 種類の手数料をサポートしています。詳細は references/custom-fees.md を参照してください。

import {
    CustomFixedFee, CustomFractionalFee, CustomRoyaltyFee, Hbar,
} from "@hiero-ledger/sdk";

const fixedFee = new CustomFixedFee()
    .setFeeCollectorAccountId(collectorId)
    .setHbarAmount(new Hbar(1));

const fractionalFee = new CustomFractionalFee()
    .setFeeCollectorAccountId(collectorId)
    .setNumerator(1).setDenominator(100)  // 1%
    .setMin(1).setMax(1000);

const royaltyFee = new CustomRoyaltyFee()
    .setFeeCollectorAccountId(collectorId)
    .setNumerator(5).setDenominator(100)  // 5%
    .setFallbackFee(
        new CustomFixedFee().setHbarAmount(new Hbar(2))
    );

await new TokenCreateTransaction()
    .setCustomFees([fixedFee, fractionalFee])
    // ... other fields
    .execute(client);

よくある落とし穴

  1. 送金前の関連付け: 受信者はトークンに関連付けるか、自動関連付けスロットを持っている必要があります。これがないと、送金は TOKEN_NOT_ASSOCIATED_TO_ACCOUNT で失敗します。

  2. 符号付き金額: addTokenTransfer は符号付き金額を使用します。送信者は負の値、受信者は正の値になります。合計がゼロになる必要があります。

  3. NFT には小数桁も初期供給量もありません: TokenType.NonFungibleUnique を設定し、シリアルを個別にミントします。

  4. adminKey がないとキーは永続的: 管理者キーがない場合、トークンを更新または削除できず、他のキーも変更できません。

  5. KYC ゲート: トークンに kycKey がある場合、アカウントはそのトークンでトランザクションを行う前に KYC 承認を受ける必要があります。

  6. ミント/バーンには供給キー: 後でミントまたはバーンを行うには、作成時に供給キーが設定されている必要があります。

  7. トレジャリーの自動関連付け: トレジャリーアカウントはトークンに自動的に関連付けられます。

  8. マルチシグ前のフリーズ: 複数の当事者が署名する必要がある場合、まず freezeWith(client) を呼び出し、その後 .sign(key) 呼び出しをチェーンします。

参照ファイル

  • references/api-reference.md — すべての HTS トランザクションおよびクエリクラスとそのメソッドの完全なリスト
  • references/custom-fees.md — 固定手数料、割合手数料、ロイヤルティ手数料の詳細ガイド

コメント