Builds and signs Hedera transactions for the Consensus, Crypto, Token, File and Schedule services.
The flow follows the Hedera HAPI: build a TransactionBody, encode it, sign
the exact bodyBytes with the operator key (and any additional :signers),
wrap them in a SignedTransaction (bodyBytes + signature map) and finally a
Transaction (signedTransactionBytes). The signature is computed over the
precise bodyBytes that are transmitted.
The wire encoding is handled by the protoc-generated Hedera.Pb.* modules
(see priv/protos/hedera_min.proto); this module maps the SDK's structs onto
those messages. Field numbers therefore live in the .proto, validated
end-to-end against a live node by the gRPC layer.
Summary
Functions
Build + sign a cryptoApproveAllowance — authorize a spender to move the
owner's assets without the owner's key. Opts
Build + sign a contractCall. Required: :contract (a ContractId). Opts:
:gas (default 50 000), :amount (tinybars to send), :function_parameters
(ABI-encoded call data). The return value is in the record, not the receipt.
Build + sign a contractCreateInstance. Provide the bytecode either inline via
:bytecode (EVM init bytecode) or by :file (a FileId holding it). Opts:
:gas (default 100 000), :admin_key, :initial_balance,
:constructor_parameters, :auto_renew_period, :contract_memo. The new
contract id is returned in the receipt.
Build + sign a consensusCreateTopic transaction. Optional: :memo, :max_fee.
Build + sign a cryptoCreateAccount. Opts: :key (the new account's
PublicKey; defaults to the operator's key), :initial_balance (tinybars),
:receiver_sig_required, :auto_renew_period, :account_memo,
:max_automatic_token_associations. The new account's id is returned in the
receipt's account_id.
Build + sign a cryptoDelete. Required: :account (the account to delete). Its
remaining hbar goes to :transfer_account (defaults to the operator). The
deleted account's key must sign (pass via :signers when not the operator).
Build + sign a cryptoTransfer of HBAR and/or HTS tokens. Opts: :transfers
({%AccountId{}, tinybars} list), :token_transfers
({%TokenId{}, [{%AccountId{}, amount}]} list), :nft_transfers
({%TokenId{}, [{sender, receiver, serial}]} list). Amounts are sint64
(ZigZag); each currency must net to zero. Optional: :memo, :max_fee.
Build + sign a cryptoUpdateAccount. Required: :account. Only the fields you
pass are changed — :key (new PublicKey), :auto_renew_period,
:receiver_sig_required, :account_memo. The account's existing key must sign
(pass it via :signers when it is not the operator); a new :key must sign too.
Build + sign a cryptoDeleteAllowance — remove NFT-serial allowances. Opt
:nft_allowances is a list of {token, owner, serials}. (HBAR/fungible
allowances are removed by approving amount 0.)
Build + sign an ethereumTransaction. Required: :ethereum_data (a complete,
signed EIP-1559 transaction, e.g. from Hedera.Ethereum.sign_eip1559/2). Opts:
:call_data (a FileId holding large calldata), :max_gas_allowance
(tinybars the payer will cover if the Ethereum sender can't, default 0). The
operator is the Hedera-side payer; the Ethereum signature authorizes the EVM call.
Build + sign a fileAppend. Required: :file, :contents. Needs the file's key(s).
Build + sign a fileCreate. Opts: :contents, :keys (a list of PublicKeys;
defaults to the operator's key), :expiration_seconds, :file_memo.
Build + sign a fileDelete. Required: :file. Needs the file's key(s).
Build + sign a fileUpdate. Required: :file. Optional: :contents, :keys, :expiration_seconds.
Build + sign a scheduleCreate wrapping an HBAR/token transfer (:transfers,
:token_transfers, :nft_transfers describe the scheduled transaction).
Optional: :admin_key, :schedule_memo.
Build + sign a scheduleSign. Required: :schedule_id.
Build + sign a consensusSubmitMessage transaction. Required opts:
:operator_id, :operator_key, :node_account_id, :topic_id, :message.
Optional: :max_fee, :memo.
Build + sign a tokenAssociate. Required: :account, :tokens (list of TokenId).
Build + sign a tokenBurn. Required: :token, :amount.
Build + sign a tokenCreation. Required: :treasury. Common opts: :name,
:symbol, :decimals, :initial_supply, :token_type (:fungible | :nft),
:supply_type (:infinite | :finite), :max_supply, :token_memo,
:auto_renew_account, :auto_renew_period, and key opts :admin_key,
:supply_key, :kyc_key, :freeze_key, :wipe_key, :pause_key,
:fee_schedule_key (required to later update the custom-fee schedule).
Build + sign a tokenDeletion. Required: :token. Needs the token's admin key.
Build + sign a tokenDissociate. Required: :account, :tokens. The account
must sign (pass its key via :signers when it is not the operator).
Build + sign a tokenFeeScheduleUpdate — replace a token's custom-fee schedule.
Required: :token. :custom_fees is a list of fee specs (maps), each with a
:collector account and a :type
Build + sign a tokenFreezeAccount. Required: :token, :account. Needs the freeze key.
Build + sign a tokenGrantKyc. Required: :token, :account. Needs the KYC key.
Build + sign a tokenMint. Required: :token. Opts: :amount (fungible) or :metadata (NFT).
Build + sign a tokenPause. Required: :token. Needs the pause key.
Build + sign a tokenRevokeKyc. Required: :token, :account. Needs the KYC key.
Build + sign a tokenUnfreezeAccount. Required: :token, :account. Needs the freeze key.
Build + sign a tokenUnpause. Required: :token. Needs the pause key.
Build + sign a tokenUpdate. Required: :token. Only fields you pass change —
:name, :symbol, :treasury, :token_memo, :auto_renew_account,
:auto_renew_period, and key opts :admin_key, :kyc_key, :freeze_key,
:wipe_key, :supply_key, :pause_key, :fee_schedule_key. Needs the admin key.
Build + sign a tokenWipeAccount. Required: :token, :account. For fungible
tokens pass :amount; for NFTs pass :serials. Needs the wipe key.
Types
@type build_result() :: %{ transaction: binary(), transaction_id: Hedera.TransactionId.t() }
Functions
@spec approve_allowance(keyword()) :: build_result()
Build + sign a cryptoApproveAllowance — authorize a spender to move the
owner's assets without the owner's key. Opts:
:hbar_allowances—{owner, spender, amount}(tinybars).:token_allowances—{token, owner, spender, amount}(fungible units).:nft_allowances—{token, owner, spender, serials}(a list of serials) or{token, owner, spender, :all}(approve for every serial of the token).
Each owner must sign; pass their keys via :signers when they aren't the operator.
@spec contract_call(keyword()) :: build_result()
Build + sign a contractCall. Required: :contract (a ContractId). Opts:
:gas (default 50 000), :amount (tinybars to send), :function_parameters
(ABI-encoded call data). The return value is in the record, not the receipt.
@spec contract_create(keyword()) :: build_result()
Build + sign a contractCreateInstance. Provide the bytecode either inline via
:bytecode (EVM init bytecode) or by :file (a FileId holding it). Opts:
:gas (default 100 000), :admin_key, :initial_balance,
:constructor_parameters, :auto_renew_period, :contract_memo. The new
contract id is returned in the receipt.
@spec create_topic(keyword()) :: build_result()
Build + sign a consensusCreateTopic transaction. Optional: :memo, :max_fee.
@spec crypto_create(keyword()) :: build_result()
Build + sign a cryptoCreateAccount. Opts: :key (the new account's
PublicKey; defaults to the operator's key), :initial_balance (tinybars),
:receiver_sig_required, :auto_renew_period, :account_memo,
:max_automatic_token_associations. The new account's id is returned in the
receipt's account_id.
@spec crypto_delete(keyword()) :: build_result()
Build + sign a cryptoDelete. Required: :account (the account to delete). Its
remaining hbar goes to :transfer_account (defaults to the operator). The
deleted account's key must sign (pass via :signers when not the operator).
@spec crypto_transfer(keyword()) :: build_result()
Build + sign a cryptoTransfer of HBAR and/or HTS tokens. Opts: :transfers
({%AccountId{}, tinybars} list), :token_transfers
({%TokenId{}, [{%AccountId{}, amount}]} list), :nft_transfers
({%TokenId{}, [{sender, receiver, serial}]} list). Amounts are sint64
(ZigZag); each currency must net to zero. Optional: :memo, :max_fee.
@spec crypto_update(keyword()) :: build_result()
Build + sign a cryptoUpdateAccount. Required: :account. Only the fields you
pass are changed — :key (new PublicKey), :auto_renew_period,
:receiver_sig_required, :account_memo. The account's existing key must sign
(pass it via :signers when it is not the operator); a new :key must sign too.
@spec delete_nft_allowance(keyword()) :: build_result()
Build + sign a cryptoDeleteAllowance — remove NFT-serial allowances. Opt
:nft_allowances is a list of {token, owner, serials}. (HBAR/fungible
allowances are removed by approving amount 0.)
@spec ethereum(keyword()) :: build_result()
Build + sign an ethereumTransaction. Required: :ethereum_data (a complete,
signed EIP-1559 transaction, e.g. from Hedera.Ethereum.sign_eip1559/2). Opts:
:call_data (a FileId holding large calldata), :max_gas_allowance
(tinybars the payer will cover if the Ethereum sender can't, default 0). The
operator is the Hedera-side payer; the Ethereum signature authorizes the EVM call.
@spec file_append(keyword()) :: build_result()
Build + sign a fileAppend. Required: :file, :contents. Needs the file's key(s).
@spec file_create(keyword()) :: build_result()
Build + sign a fileCreate. Opts: :contents, :keys (a list of PublicKeys;
defaults to the operator's key), :expiration_seconds, :file_memo.
@spec file_delete(keyword()) :: build_result()
Build + sign a fileDelete. Required: :file. Needs the file's key(s).
@spec file_update(keyword()) :: build_result()
Build + sign a fileUpdate. Required: :file. Optional: :contents, :keys, :expiration_seconds.
@spec schedule_create(keyword()) :: build_result()
Build + sign a scheduleCreate wrapping an HBAR/token transfer (:transfers,
:token_transfers, :nft_transfers describe the scheduled transaction).
Optional: :admin_key, :schedule_memo.
@spec schedule_sign(keyword()) :: build_result()
Build + sign a scheduleSign. Required: :schedule_id.
@spec submit_message(keyword()) :: build_result()
Build + sign a consensusSubmitMessage transaction. Required opts:
:operator_id, :operator_key, :node_account_id, :topic_id, :message.
Optional: :max_fee, :memo.
@spec token_associate(keyword()) :: build_result()
Build + sign a tokenAssociate. Required: :account, :tokens (list of TokenId).
@spec token_burn(keyword()) :: build_result()
Build + sign a tokenBurn. Required: :token, :amount.
@spec token_create(keyword()) :: build_result()
Build + sign a tokenCreation. Required: :treasury. Common opts: :name,
:symbol, :decimals, :initial_supply, :token_type (:fungible | :nft),
:supply_type (:infinite | :finite), :max_supply, :token_memo,
:auto_renew_account, :auto_renew_period, and key opts :admin_key,
:supply_key, :kyc_key, :freeze_key, :wipe_key, :pause_key,
:fee_schedule_key (required to later update the custom-fee schedule).
@spec token_delete(keyword()) :: build_result()
Build + sign a tokenDeletion. Required: :token. Needs the token's admin key.
@spec token_dissociate(keyword()) :: build_result()
Build + sign a tokenDissociate. Required: :account, :tokens. The account
must sign (pass its key via :signers when it is not the operator).
@spec token_fee_schedule_update(keyword()) :: build_result()
Build + sign a tokenFeeScheduleUpdate — replace a token's custom-fee schedule.
Required: :token. :custom_fees is a list of fee specs (maps), each with a
:collector account and a :type:
%{type: :fixed, amount:, denominating_token: TokenId | nil, collector:}%{type: :fractional, numerator:, denominator:, minimum:, maximum:, net_of_transfers:, collector:}%{type: :royalty, numerator:, denominator:, fallback_amount:, fallback_token:, collector:}
Needs the token's fee-schedule key.
@spec token_freeze(keyword()) :: build_result()
Build + sign a tokenFreezeAccount. Required: :token, :account. Needs the freeze key.
@spec token_grant_kyc(keyword()) :: build_result()
Build + sign a tokenGrantKyc. Required: :token, :account. Needs the KYC key.
@spec token_mint(keyword()) :: build_result()
Build + sign a tokenMint. Required: :token. Opts: :amount (fungible) or :metadata (NFT).
@spec token_pause(keyword()) :: build_result()
Build + sign a tokenPause. Required: :token. Needs the pause key.
@spec token_revoke_kyc(keyword()) :: build_result()
Build + sign a tokenRevokeKyc. Required: :token, :account. Needs the KYC key.
@spec token_unfreeze(keyword()) :: build_result()
Build + sign a tokenUnfreezeAccount. Required: :token, :account. Needs the freeze key.
@spec token_unpause(keyword()) :: build_result()
Build + sign a tokenUnpause. Required: :token. Needs the pause key.
@spec token_update(keyword()) :: build_result()
Build + sign a tokenUpdate. Required: :token. Only fields you pass change —
:name, :symbol, :treasury, :token_memo, :auto_renew_account,
:auto_renew_period, and key opts :admin_key, :kyc_key, :freeze_key,
:wipe_key, :supply_key, :pause_key, :fee_schedule_key. Needs the admin key.
@spec token_wipe(keyword()) :: build_result()
Build + sign a tokenWipeAccount. Required: :token, :account. For fungible
tokens pass :amount; for NFTs pass :serials. Needs the wipe key.