Overview
HTS represents fungible assets as native ledger entities with optional compliance controls beyond typical ERC-20 deployments. This skill encodes the procedural mapping between business roles (treasury, compliance, operations) and Hedera key fields documented under Token Properties.
When to use this skill
- Designing treasury + compliance separation via distinct keys.
- Choosing infinite vs finite supply (
TokenSupplyType). - Debugging association/KYC/freeze precedence issues before transfers succeed.
Prerequisites
- Funded operator account on intended network.
- Treasury account — defaults to operator in reference scripts; production uses cold treasury.
Workflow
Model roles → keys — See references/key-roles-taxonomy.md.
Create token —
TokenCreateTransactionwith name, symbol, decimals, initial supply, treasury, keys.await new TokenCreateTransaction() .setTokenName("Demo USD") .setTokenSymbol("DUSD") .setDecimals(8) .setInitialSupply(1_000_000) .setTreasuryAccountId(treasuryId) .setTokenType(TokenType.FungibleCommon) .setSupplyType(TokenSupplyType.Infinite) .setAdminKey(adminKey) .setSupplyKey(supplyKey) // ... optional compliance keysReference: scripts/create-fungible-token.js.
Associate recipients — Accounts must opt-in via
TokenAssociateTransactionbefore receiving tokens (unless auto-account patterns apply — verify docs).Transfers —
TransferTransaction.addTokenTransfer(tokenId, account, amount)with signed payer/treasury as required.Compliance toggles —
TokenGrantKycTransaction,TokenRevokeKycTransaction,TokenFreezeTransaction,TokenUnfreezeTransaction,TokenWipeTransaction,TokenPauseTransaction,TokenUnpauseTransaction.Mint/burn —
TokenMintTransaction,TokenBurnTransactionrequiresupplyKeysignatures.
Examples
Example 1
“Create an infinite-supply governance token with separate admin and supply keys.”
Provision distinct PrivateKeys, assign adminKey vs supplyKey, leave mint-only authority with multisig supply key if policy demands.
Example 2
“Investors must pass KYC before receiving allocations.”
Enable kycKey, default deny via documentation + off-chain checks, call grant KYC before first transfer.
Example 3
“Pause trading during an incident.”
Use pauseKey, document who may unpause; communicate regulatory expectations if investors are retail.
Troubleshooting
| Issue | Meaning |
|---|---|
TOKEN_NOT_ASSOCIATED_TO_ACCOUNT |
Recipient never associated |
ACCOUNT_KYC_NOT_GRANTED_FOR_TOKEN |
KYC flag blocking receipt |
TOKEN_IS_PAUSED |
Global pause active |
INSUFFICIENT_TOKEN_BALANCE |
Treasury empty / wrong decimals math |
References
- Local: references/key-roles-taxonomy.md, references/compliance-config.md
- Docs: Define a token, Custom token fees