-
Notifications
You must be signed in to change notification settings - Fork 63
Description
🧠 Advanced
This issue is well-suited for contributors who are very familiar with the Hiero C++ SDK and enjoy working with its core abstractions and design patterns.
Advanced Issues often involve:
- Exploring and shaping SDK architecture
- Reasoning about trade-offs and long-term impact
- Working across multiple modules or systems
- Updating tests, examples, and documentation alongside code
The goal is to support thoughtful, high-impact contributions in a clear and collaborative way.
🐞 Problem Description
The Hiero C++ SDK doesn't currently support fee estimate queries as defined in HIP-1261: Simple Fees. This makes it harder for developers to programmatically estimate transaction fees before execution.
Background
HIP-1261 introduces a simplified fee model with three components:
- Node fee: Paid to the submitting node (based on bytes and signatures)
- Network fee: Covers gossip, consensus, signature verification, and storage
- Service fee: Covers execution costs and state persistence
The fee estimation API allows users to predict transaction costs before submission, supporting two modes:
- STATE mode (default): Estimates using the mirror node's latest known state
- INTRINSIC mode: Estimates from the payload alone, ignoring state-dependent costs
💡 Proposed / Expected Outcome
Implement full SDK support for HIP-1261 fee estimation following the design document provided:
Design Document: https://github.com/hiero-ledger/sdk-collaboration-hub/blob/main/proposals/hips/hip-1261.md
Important
The implementation MUST follow the API design, class structure, and behavior defined in the design document above. This ensures consistency across all Hiero SDK implementations.
The design document specifies the following components to implement:
New Data Types
enum class FeeEstimateMode {
STATE, // Default: uses latest known state
INTRINSIC // Ignores state-dependent factors
};
class FeeExtra {
std::string name; // Extra fee name (e.g., "Signatures", "Bytes")
uint32_t included; // Count included for free
uint32_t count; // Actual count received
uint32_t charged; // max(0, count - included)
uint64_t feePerUnit; // Fee per unit in tinycents
uint64_t subtotal; // charged * feePerUnit
};
class FeeEstimate {
uint64_t base; // Base fee in tinycents
std::vector<FeeExtra> extras;
};
class NetworkFee {
uint32_t multiplier; // Multiplied by node fee
uint64_t subtotal; // node.subtotal * multiplier
};
class FeeEstimateResponse {
FeeEstimateMode mode;
NetworkFee networkFee;
FeeEstimate nodeFee;
FeeEstimate serviceFee;
std::vector<std::string> notes;
uint64_t total; // Sum of all subtotals
};New Query Class
class FeeEstimateQuery : public Query<FeeEstimateResponse> {
FeeEstimateQuery& setMode(FeeEstimateMode mode);
FeeEstimateMode getMode() const;
FeeEstimateQuery& setTransaction(const Transaction& transaction);
// Transaction is automatically frozen if not already frozen
};Transaction Extension
class Transaction {
// New method to create a fee estimate query
FeeEstimateQuery estimateFee() const;
};🧠 Implementation & Design Notes
Design Document (Authoritative Source)
Important
All implementation details, API signatures, class names, and behaviors are defined in the design document. The design document is the authoritative source for this implementation.
Design Document: https://github.com/hiero-ledger/sdk-collaboration-hub/blob/main/proposals/hips/hip-1261.md
The design document includes:
- Complete API specifications for all new types
- Method signatures and expected behavior
- Test plan with specific test cases
- Code examples demonstrating usage
Contributors should implement the C++ equivalent of the APIs defined in the design document, following existing SDK patterns and conventions.
Key Implementation Areas (per Design Document)
-
Data model classes (
FeeExtra,FeeEstimate,NetworkFee,FeeEstimateResponse)- Immutable value types with appropriate getters
- Serialization/deserialization from Mirror Node response
-
FeeEstimateMode enum
- Two modes:
STATEandINTRINSIC - Default to
STATEwhen not specified
- Two modes:
-
FeeEstimateQuery class
- Extends existing
Querybase class patterns - Integrates with Mirror Node gRPC
NetworkService.getFeeEstimate - Auto-freezes transaction if not already frozen
- Implements retry policy (retry on
UNAVAILABLE,DEADLINE_EXCEEDED; no retry onINVALID_ARGUMENT)
- Extends existing
-
Chunked transaction handling
- For
FileAppendTransactionandTopicMessageSubmitTransaction - Aggregate fees across all chunks into single response
total = sum of all chunk fees
- For
-
Transaction.estimateFee() method
- Convenience method to create
FeeEstimateQueryfrom any transaction
- Convenience method to create
Fee Calculation Logic
From HIP-1261:
nodeFee = node.baseFee + sum(extras)
networkFee = nodeFee * network.multiplier
serviceFee = service.baseFee + sum(service.extras)
total = nodeFee + networkFee + serviceFee
Mirror Node Integration
The query communicates with the Mirror Node REST API:
POST /api/v1/network/fees?mode=STATE
Content-Type: application/protobuf
<Transaction protobuf binary>
Files to Create/Modify
New files (suggested structure):
src/sdk/main/include/FeeEstimateMode.hsrc/sdk/main/include/FeeExtra.hsrc/sdk/main/include/FeeEstimate.hsrc/sdk/main/include/NetworkFee.hsrc/sdk/main/include/FeeEstimateResponse.hsrc/sdk/main/include/FeeEstimateQuery.hsrc/sdk/main/src/FeeEstimateQuery.cc
Modified files:
- Transaction base class (add
estimateFee()method) - Potentially chunked transaction classes for fee aggregation
Test Plan
The design document includes a comprehensive test plan:
- Basic functionality: STATE mode, INTRINSIC mode, default mode behavior
- Transaction type coverage: TokenCreate, TokenMint, TopicCreate, ContractCreate, FileCreate
- Fee component validation: Verify
network.subtotal = node.subtotal * multiplier, verify total calculation - Error handling: Malformed transactions, service unavailable, timeouts
- Chunked transactions: FileAppendTransaction, TopicMessageSubmitTransaction aggregation
✅ Acceptance Criteria
A pull request for this issue should:
- Follow the design document: Implementation matches the API design, class structure, and behavior specified in the design document
- Implement all new data types as specified (
FeeEstimateMode,FeeExtra,FeeEstimate,NetworkFee,FeeEstimateResponse) - Implement
FeeEstimateQueryclass as specified in the design document - Add
estimateFee()method to Transaction base class - Handle chunked transaction fee aggregation per design document
- Implement retry policy as specified (retry on
UNAVAILABLE/DEADLINE_EXCEEDED, no retry onINVALID_ARGUMENT) - Auto-freeze transactions that aren't already frozen
- Pass all test cases: Implement tests covering the test plan defined in the design document
- Maintain backwards compatibility
- Follow existing architectural and C++ conventions
- Provide usage examples
- Update relevant documentation
- Pass all CI checks
📚 Additional Context, Links, or Prior Art
References
| Document | Purpose |
|---|---|
| SDK Design Document | Authoritative source for implementation - defines APIs, behavior, and test plan |
| HIP-1261 (Simple Fees) | Background context - explains the fee model and Mirror Node API |
Fee Schedule Details
Fees are defined in tinycents (10^8 tinycents = 1 cent USD). The fee schedule is stored in system file 0.0.113.
Common extras:
| Extra | Description |
|---|---|
| Signatures | Number of signatures on the transaction |
| Bytes | Size of the transaction in protobuf bytes |
| Keys | Number of keys being defined |
| Gas | Gas cost for smart contract operations |
| TokenTypes | Number of token types referenced |
| NFTSerials | Number of distinct NFT serials |
Cross-SDK Alignment
The design document ensures consistency across all Hiero SDK implementations. By following the design document, this C++ implementation will align with the Java, JavaScript, Go, and other SDK implementations.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status