-
Notifications
You must be signed in to change notification settings - Fork 9
feat(fees): integrate fee management #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
CharlVS
merged 3 commits into
dev
from
codex/implement-fee-management-in-withdrawal-manager
Jul 25, 2025
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
...odo_defi_rpc_methods/lib/src/rpc_methods/fee_management/fee_management_rpc_namespace.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import 'package:komodo_defi_rpc_methods/src/internal_exports.dart'; | ||
| import 'package:komodo_defi_types/komodo_defi_types.dart'; | ||
|
|
||
| class FeeManagementMethodsNamespace extends BaseRpcMethodNamespace { | ||
| FeeManagementMethodsNamespace(super.client); | ||
|
|
||
| Future<GetEthEstimatedFeePerGasResponse> getEthEstimatedFeePerGas({ | ||
| required String coin, | ||
| required FeeEstimatorType estimatorType, | ||
| String? rpcPass, | ||
| }) => execute( | ||
| GetEthEstimatedFeePerGasRequest( | ||
| rpcPass: rpcPass ?? this.rpcPass ?? '', | ||
| coin: coin, | ||
| estimatorType: estimatorType, | ||
| ), | ||
| ); | ||
|
|
||
| Future<GetSwapTransactionFeePolicyResponse> getSwapTransactionFeePolicy({ | ||
| required String coin, | ||
| String? rpcPass, | ||
| }) => execute( | ||
| GetSwapTransactionFeePolicyRequest( | ||
| rpcPass: rpcPass ?? this.rpcPass ?? '', | ||
| coin: coin, | ||
| ), | ||
| ); | ||
|
|
||
| Future<SetSwapTransactionFeePolicyResponse> setSwapTransactionFeePolicy({ | ||
| required String coin, | ||
| required FeePolicy swapTxFeePolicy, | ||
| String? rpcPass, | ||
| }) => execute( | ||
| SetSwapTransactionFeePolicyRequest( | ||
| rpcPass: rpcPass ?? this.rpcPass ?? '', | ||
| coin: coin, | ||
| swapTxFeePolicy: swapTxFeePolicy, | ||
| ), | ||
| ); | ||
| } |
44 changes: 44 additions & 0 deletions
44
...do_defi_rpc_methods/lib/src/rpc_methods/fee_management/get_eth_estimated_fee_per_gas.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import 'package:komodo_defi_rpc_methods/src/internal_exports.dart'; | ||
| import 'package:komodo_defi_types/komodo_defi_type_utils.dart'; | ||
| import 'package:komodo_defi_types/komodo_defi_types.dart'; | ||
|
|
||
| class GetEthEstimatedFeePerGasRequest | ||
| extends | ||
| BaseRequest<GetEthEstimatedFeePerGasResponse, GeneralErrorResponse> { | ||
| GetEthEstimatedFeePerGasRequest({ | ||
| required super.rpcPass, | ||
| required this.coin, | ||
| required this.estimatorType, | ||
| }) : super(method: 'get_eth_estimated_fee_per_gas', mmrpc: '2.0'); | ||
|
|
||
| final String coin; | ||
| final FeeEstimatorType estimatorType; | ||
|
|
||
| @override | ||
| Map<String, dynamic> toJson() => { | ||
| ...super.toJson(), | ||
| 'params': {'coin': coin, 'estimator_type': estimatorType.toString()}, | ||
| }; | ||
|
|
||
| @override | ||
| GetEthEstimatedFeePerGasResponse parse(Map<String, dynamic> json) => | ||
| GetEthEstimatedFeePerGasResponse.parse(json); | ||
| } | ||
|
|
||
| class GetEthEstimatedFeePerGasResponse extends BaseResponse { | ||
| GetEthEstimatedFeePerGasResponse({ | ||
| required super.mmrpc, | ||
| required this.result, | ||
| }); | ||
|
|
||
| factory GetEthEstimatedFeePerGasResponse.parse(Map<String, dynamic> json) => | ||
| GetEthEstimatedFeePerGasResponse( | ||
| mmrpc: json.value<String>('mmrpc'), | ||
| result: EthEstimatedFeePerGas.fromJson(json.value<JsonMap>('result')), | ||
| ); | ||
|
|
||
| final EthEstimatedFeePerGas result; | ||
|
|
||
| @override | ||
| Map<String, dynamic> toJson() => {'mmrpc': mmrpc, 'result': result.toJson()}; | ||
| } |
46 changes: 46 additions & 0 deletions
46
..._defi_rpc_methods/lib/src/rpc_methods/fee_management/get_swap_transaction_fee_policy.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| import 'package:komodo_defi_rpc_methods/src/internal_exports.dart'; | ||
| import 'package:komodo_defi_types/komodo_defi_type_utils.dart'; | ||
| import 'package:komodo_defi_types/komodo_defi_types.dart'; | ||
|
|
||
| class GetSwapTransactionFeePolicyRequest | ||
| extends | ||
| BaseRequest<GetSwapTransactionFeePolicyResponse, GeneralErrorResponse> { | ||
| GetSwapTransactionFeePolicyRequest({ | ||
| required super.rpcPass, | ||
| required this.coin, | ||
| }) : super(method: 'get_swap_transaction_fee_policy', mmrpc: '2.0'); | ||
|
|
||
| final String coin; | ||
|
|
||
| @override | ||
| Map<String, dynamic> toJson() => { | ||
| ...super.toJson(), | ||
| 'params': {'coin': coin}, | ||
| }; | ||
|
|
||
| @override | ||
| GetSwapTransactionFeePolicyResponse parse(Map<String, dynamic> json) => | ||
| GetSwapTransactionFeePolicyResponse.parse(json); | ||
| } | ||
|
|
||
| class GetSwapTransactionFeePolicyResponse extends BaseResponse { | ||
| GetSwapTransactionFeePolicyResponse({ | ||
| required super.mmrpc, | ||
| required this.result, | ||
| }); | ||
|
|
||
| factory GetSwapTransactionFeePolicyResponse.parse( | ||
| Map<String, dynamic> json, | ||
| ) => GetSwapTransactionFeePolicyResponse( | ||
| mmrpc: json.value<String>('mmrpc'), | ||
| result: FeePolicy.fromString(json.value<String>('result')), | ||
| ); | ||
|
|
||
| final FeePolicy result; | ||
|
|
||
| @override | ||
| Map<String, dynamic> toJson() => { | ||
| 'mmrpc': mmrpc, | ||
| 'result': result.toString(), | ||
| }; | ||
| } |
48 changes: 48 additions & 0 deletions
48
..._defi_rpc_methods/lib/src/rpc_methods/fee_management/set_swap_transaction_fee_policy.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| import 'package:komodo_defi_rpc_methods/src/internal_exports.dart'; | ||
| import 'package:komodo_defi_types/komodo_defi_type_utils.dart'; | ||
| import 'package:komodo_defi_types/komodo_defi_types.dart'; | ||
|
|
||
| class SetSwapTransactionFeePolicyRequest | ||
| extends | ||
| BaseRequest<SetSwapTransactionFeePolicyResponse, GeneralErrorResponse> { | ||
| SetSwapTransactionFeePolicyRequest({ | ||
| required super.rpcPass, | ||
| required this.coin, | ||
| required this.swapTxFeePolicy, | ||
| }) : super(method: 'set_swap_transaction_fee_policy', mmrpc: '2.0'); | ||
|
|
||
| final String coin; | ||
| final FeePolicy swapTxFeePolicy; | ||
|
|
||
| @override | ||
| Map<String, dynamic> toJson() => { | ||
| ...super.toJson(), | ||
| 'params': {'coin': coin, 'swap_tx_fee_policy': swapTxFeePolicy.toString()}, | ||
| }; | ||
|
|
||
| @override | ||
| SetSwapTransactionFeePolicyResponse parse(Map<String, dynamic> json) => | ||
| SetSwapTransactionFeePolicyResponse.parse(json); | ||
| } | ||
|
|
||
| class SetSwapTransactionFeePolicyResponse extends BaseResponse { | ||
| SetSwapTransactionFeePolicyResponse({ | ||
| required super.mmrpc, | ||
| required this.result, | ||
| }); | ||
|
|
||
| factory SetSwapTransactionFeePolicyResponse.parse( | ||
| Map<String, dynamic> json, | ||
| ) => SetSwapTransactionFeePolicyResponse( | ||
| mmrpc: json.value<String>('mmrpc'), | ||
| result: FeePolicy.fromString(json.value<String>('result')), | ||
| ); | ||
|
|
||
| final FeePolicy result; | ||
|
|
||
| @override | ||
| Map<String, dynamic> toJson() => { | ||
| 'mmrpc': mmrpc, | ||
| 'result': result.toString(), | ||
| }; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| import 'package:komodo_defi_types/komodo_defi_types.dart'; | ||
|
|
||
| /// Manages cryptocurrency transaction fee operations and policies. | ||
| /// | ||
| /// The [FeeManager] provides functionality for: | ||
| /// - Retrieving estimated gas fees for Ethereum-based transactions | ||
| /// - Getting and setting fee policies for swap transactions | ||
| /// - Managing fee-related configuration for blockchain operations | ||
| /// | ||
| /// This manager abstracts away the complexity of fee estimation and management, | ||
| /// providing a simple interface for applications to work with transaction fees | ||
| /// across different blockchain protocols. | ||
| /// | ||
| /// Usage example: | ||
| /// ```dart | ||
| /// final feeManager = FeeManager(apiClient); | ||
| /// | ||
| /// // Get ETH gas fee estimates | ||
| /// final gasEstimates = await feeManager.getEthEstimatedFeePerGas('ETH'); | ||
| /// print('Slow fee: ${gasEstimates.slow.maxFeePerGas} gwei'); | ||
| /// print('Medium fee: ${gasEstimates.medium.maxFeePerGas} gwei'); | ||
| /// print('Fast fee: ${gasEstimates.fast.maxFeePerGas} gwei'); | ||
| /// | ||
| /// // Get current swap fee policy for a coin | ||
| /// final policy = await feeManager.getSwapTransactionFeePolicy('KMD'); | ||
| /// print('Current fee policy: ${policy.type}'); | ||
| /// | ||
| /// // Update fee policy if needed | ||
| /// if (policy.type != 'standard') { | ||
| /// final newPolicy = FeePolicy(type: 'standard', ...); | ||
| /// await feeManager.setSwapTransactionFeePolicy('KMD', newPolicy); | ||
| /// } | ||
| /// ``` | ||
| class FeeManager { | ||
| /// Creates a new [FeeManager] instance. | ||
| /// | ||
| /// Requires: | ||
| /// - [_client] - API client for making RPC calls to fee management endpoints | ||
| FeeManager(this._client); | ||
|
|
||
| final ApiClient _client; | ||
|
|
||
| /// Retrieves estimated fee per gas for Ethereum-based transactions. | ||
| /// | ||
| /// This method provides up-to-date gas fee estimates for Ethereum-compatible | ||
| /// chains with different speed options (slow, medium, fast). | ||
| /// | ||
| /// Parameters: | ||
| /// - [coin] - The ticker symbol of the coin (e.g., 'ETH', 'MATIC') | ||
| /// - [estimatorType] - The type of estimator to use (default: simple) | ||
| /// | ||
| /// Returns a [Future<EthEstimatedFeePerGas>] containing gas fee estimates at | ||
| /// different priority levels: | ||
| /// - `slow` - Lower cost but potentially longer confirmation time | ||
| /// - `medium` - Balanced cost and confirmation time | ||
| /// - `fast` - Higher cost for faster confirmation | ||
| /// | ||
| /// Each estimate includes: | ||
| /// - `maxFeePerGas` - Maximum fee per gas unit | ||
| /// - `maxPriorityFeePerGas` - Maximum priority fee per gas unit | ||
| /// | ||
| /// Example: | ||
| /// ```dart | ||
| /// final estimates = await feeManager.getEthEstimatedFeePerGas('ETH'); | ||
| /// | ||
| /// // Choose a fee based on desired confirmation speed | ||
| /// final selectedFee = estimates.medium; | ||
| /// | ||
| /// print('Max fee: ${selectedFee.maxFeePerGas} gwei'); | ||
| /// print('Max priority fee: ${selectedFee.maxPriorityFeePerGas} gwei'); | ||
| /// ``` | ||
| Future<EthEstimatedFeePerGas> getEthEstimatedFeePerGas( | ||
| String coin, { | ||
| FeeEstimatorType estimatorType = FeeEstimatorType.simple, | ||
| }) async { | ||
| final response = await _client.rpc.feeManagement.getEthEstimatedFeePerGas( | ||
| coin: coin, | ||
| estimatorType: estimatorType, | ||
| ); | ||
| return response.result; | ||
| } | ||
|
|
||
| /// Retrieves the current fee policy for swap transactions of a specific coin. | ||
| /// | ||
| /// Fee policies determine how transaction fees are calculated and applied | ||
| /// for swap operations involving the specified coin. | ||
| /// | ||
| /// Parameters: | ||
| /// - [coin] - The ticker symbol of the coin (e.g., 'KMD', 'BTC') | ||
| /// | ||
| /// Returns a [Future<FeePolicy>] containing the current fee policy | ||
| /// configuration. | ||
| /// | ||
| /// Example: | ||
| /// ```dart | ||
| /// final policy = await feeManager.getSwapTransactionFeePolicy('KMD'); | ||
| /// | ||
| /// if (policy.type == 'utxo_per_kbyte') { | ||
| /// print('Fee rate: ${policy.feePerKbyte} sat/KB'); | ||
| /// } | ||
| /// ``` | ||
| Future<FeePolicy> getSwapTransactionFeePolicy(String coin) async { | ||
| final response = await _client.rpc.feeManagement | ||
| .getSwapTransactionFeePolicy(coin: coin); | ||
| return response.result; | ||
| } | ||
|
|
||
| /// Sets a new fee policy for swap transactions of a specific coin. | ||
| /// | ||
| /// This method allows customizing how transaction fees are calculated and | ||
| /// applied for swap operations involving the specified coin. | ||
| /// | ||
| /// Parameters: | ||
| /// - [coin] - The ticker symbol of the coin (e.g., 'KMD', 'BTC') | ||
| /// - [policy] - The new fee policy to apply | ||
| /// | ||
| /// Returns a [Future<FeePolicy>] containing the updated fee policy | ||
| /// configuration. | ||
| /// | ||
| /// Example: | ||
| /// ```dart | ||
| /// // Create a new UTXO fee policy with a specific rate | ||
| /// final newPolicy = FeePolicy( | ||
| /// type: 'utxo_per_kbyte', | ||
| /// feePerKbyte: 1000, // 1000 satoshis per kilobyte | ||
| /// ); | ||
| /// | ||
| /// final updatedPolicy = await feeManager.setSwapTransactionFeePolicy( | ||
| /// 'BTC', | ||
| /// newPolicy, | ||
| /// ); | ||
| /// | ||
| /// print('Updated fee policy: ${updatedPolicy.type}'); | ||
| /// ``` | ||
| Future<FeePolicy> setSwapTransactionFeePolicy( | ||
| String coin, | ||
| FeePolicy policy, | ||
| ) async { | ||
| final response = await _client.rpc.feeManagement | ||
| .setSwapTransactionFeePolicy(coin: coin, swapTxFeePolicy: policy); | ||
| return response.result; | ||
| } | ||
|
|
||
| /// Disposes of resources used by the FeeManager. | ||
| /// | ||
| /// This method is called when the FeeManager is no longer needed. | ||
| /// Currently, it doesn't perform any cleanup operations as the FeeManager | ||
| /// doesn't manage any resources that require explicit disposal. | ||
| /// | ||
| /// Example: | ||
| /// ```dart | ||
| /// // When done with the fee manager | ||
| /// await feeManager.dispose(); | ||
| /// ``` | ||
| Future<void> dispose() { | ||
| // No resources to dispose. Return a future that completes immediately. | ||
| return Future.value(); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.