Skip to content
Lattice

HTSAdapterLib

Git Source

Title: HTSAdapterLib

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from hiero-ledger/hiero-contracts (https://github.com/hiero-ledger/hiero-contracts)

Logic + ERC-7201 storage for the diamond's Hedera Token Service account: associations, transfers of its own balances, and creation / mint / burn of tokens it holds the keys to.

All system-contract calls are plain calls from the diamond (a facet delegatecall frame): HTS sees msg.sender == diamond, so the diamond's account is the one whose associations, balances, allowances, and keys are checked. Because that frame IS a delegatecall frame, HTS activates only delegatableContractId keys for the diamond wherever a key is actually verified, so every key this library sets on a created token uses delegatableContractId = address(this).

MEASURED CAVEAT (hedera-testnet, consensus node 0.76.3, 2026-09-12): the shorter claim that a contractId key on a diamond is simply dead is FALSE for the ordinary deployment shape. A relay-deployed contract's own account key is contractId(self), and the dispatched child transaction's payer is the diamond, so a contractId(&lt;diamond>) token key is byte-identical to the payer key and PreHandleContextImpl.requireKey elides it before verification — such a key mints fine. delegatableContractId is a different protobuf oneof, so it is genuinely required, verified and passed; it is also the only form that survives a diamond whose account key is not contractId(self), a key nested in a KeyList/ThresholdKey, or a key naming another contract. That is why this library sets it unconditionally rather than relying on the elision.

Functions

htsAdapterStorage

Returns the ERC-7201 storage struct for HTSAdapter.

function htsAdapterStorage() internal pure returns (HTSAdapterStorage storage $);

Returns

NameTypeDescription
$HTSAdapterStorage

__HTSAdapter_init

Registers the IHTSAdapter ERC-165 interface.

Must be called between preInitializer / postInitializer.

function __HTSAdapter_init() internal;

registerInterface

Writes true to the ERC-165 map slot for IHTSAdapter.

function registerInterface() internal;

isAssociated

True if the diamond is associated with token (HIP-719 facade on the token address).

function isAssociated(address token) internal view returns (bool);

Parameters

NameTypeDescription
tokenaddress

Returns

NameTypeDescription
<none>bool

isHTSToken

True if token is an HTS token.

function isHTSToken(address token) internal view returns (bool isToken);

Parameters

NameTypeDescription
tokenaddress

Returns

NameTypeDescription
isTokenbool

htsTokenType

HTS token type (0 fungible, 1 non-fungible); reverts HTSNotAToken for a non-token.

function htsTokenType(address token) internal view returns (int32 tokenType);

Parameters

NameTypeDescription
tokenaddress

Returns

NameTypeDescription
tokenTypeint32

createdTokens

The HTS tokens created by this diamond.

function createdTokens() internal view returns (address[] memory);

Returns

NameTypeDescription
<none>address[]

associateToken

Associates the diamond with token. Caller must hold HTS_MANAGER_ROLE.

function associateToken(address token) internal;

Parameters

NameTypeDescription
tokenaddress

dissociateToken

Dissociates the diamond from token. Caller must hold HTS_MANAGER_ROLE.

function dissociateToken(address token) internal;

Parameters

NameTypeDescription
tokenaddress

createFungibleToken

Creates a fungible token treasuried and key-controlled by the diamond. Caller must hold HTS_MANAGER_ROLE. Forwards msg.value as the creation fee.

function createFungibleToken(
        string calldata name,
        string calldata symbol,
        string calldata memo,
        int32 decimals,
        int64 initialSupply,
        int64 maxSupply
    ) internal returns (address token);

Parameters

NameTypeDescription
namestring
symbolstring
memostring
decimalsint32
initialSupplyint64
maxSupplyint64

Returns

NameTypeDescription
tokenaddress

createNonFungibleToken

Creates a non-fungible token treasuried and key-controlled by the diamond. Caller must hold HTS_MANAGER_ROLE. Forwards msg.value as the creation fee.

function createNonFungibleToken(string calldata name, string calldata symbol, string calldata memo, int64 maxSupply)
        internal
        returns (address token);

Parameters

NameTypeDescription
namestring
symbolstring
memostring
maxSupplyint64

Returns

NameTypeDescription
tokenaddress

transferToken

Transfers amount of token from the diamond to to. Caller must hold HTS_OPERATOR_ROLE.

function transferToken(address token, address to, int64 amount) internal;

Parameters

NameTypeDescription
tokenaddress
toaddress
amountint64

transferTokenFrom

Spends the allowance from granted the diamond: moves amount of token from from to to. Caller must hold HTS_OPERATOR_ROLE.

function transferTokenFrom(address token, address from, address to, int64 amount) internal;

Parameters

NameTypeDescription
tokenaddress
fromaddress
toaddress
amountint64

transferNFT

Transfers NFT serialNumber of token from the diamond to to. Caller must hold HTS_OPERATOR_ROLE.

function transferNFT(address token, address to, int64 serialNumber) internal;

Parameters

NameTypeDescription
tokenaddress
toaddress
serialNumberint64

mintToken

Mints to the treasury (the diamond). Caller must hold HTS_OPERATOR_ROLE.

function mintToken(address token, int64 amount, bytes[] calldata metadata)
        internal
        returns (int64 newTotalSupply, int64[] memory serialNumbers);

Parameters

NameTypeDescription
tokenaddress
amountint64
metadatabytes[]

Returns

NameTypeDescription
newTotalSupplyint64
serialNumbersint64[]

burnToken

Burns from the treasury (the diamond). Caller must hold HTS_OPERATOR_ROLE.

function burnToken(address token, int64 amount, int64[] calldata serialNumbers)
        internal
        returns (int64 newTotalSupply);

Parameters

NameTypeDescription
tokenaddress
amountint64
serialNumbersint64[]

Returns

NameTypeDescription
newTotalSupplyint64

_tokenTemplate

Builds the create-token template: diamond = treasury + auto-renew account, admin + supply keys as delegatableContractId(diamond) (the ONLY key form a facet call can activate), 90-day auto-renew.

function _tokenTemplate(string calldata name, string calldata symbol, string calldata memo, int64 maxSupply)
        private
        view
        returns (IHederaTokenService.HederaToken memory t);

Parameters

NameTypeDescription
namestring
symbolstring
memostring
maxSupplyint64

Returns

NameTypeDescription
tIHederaTokenService.HederaToken

_decodeCreate

Decodes a create* return; maps a failed frame to UNKNOWN like hiero-contracts' helper does.

function _decodeCreate(bytes4 selector, bool ok, bytes memory ret) private pure returns (address token);

Parameters

NameTypeDescription
selectorbytes4
okbool
retbytes

Returns

NameTypeDescription
tokenaddress

_callForCode

Plain call into HTS returning the response code (UNKNOWN when the frame itself failed).

function _callForCode(bytes memory data) private returns (int64 code);

Parameters

NameTypeDescription
databytes

Returns

NameTypeDescription
codeint64

_staticcall

staticcall into HTS for the view-classified getters; a halted frame surfaces as HTSCallFailed.

function _staticcall(bytes memory data) private view returns (bytes memory ret);

Parameters

NameTypeDescription
databytes

Returns

NameTypeDescription
retbytes

_check

Maps an HTS response code to the typed error for selector; no-op on SUCCESS.

function _check(bytes4 selector, int64 code, address token, address account) private pure;

Parameters

NameTypeDescription
selectorbytes4
codeint64
tokenaddress
accountaddress