Skip to content

Conversation

@tom9000
Copy link
Contributor

@tom9000 tom9000 commented Dec 18, 2025

Implements automatic fee calculation for NEAR transfers by integrating with the Bridge Indexer API.

Fixes #181

Key Features:

  • Auto-Calculation: Fetches transferred_token_fee and native_token_fee from /api/v1/transfer-fee when not explicitly provided by the user.
  • Configurable: Adds bridge_indexer_api_url to CliConfig (configurable via CLI arg or env var).
  • Fallbacks: Defaults to zero fees if the API is unconfigured, allowing custom interactions.

Safety & Hardening:

  • Validation: Emits warnings if transfer amount is 0 or if total fees are 0 (mitigating relayer rejection risks).
  • API Calls:
    • Uses reqwest with a strict 10s timeout to prevent hangs.
    • Checks HTTP status codes (handling 404/500 errors gracefully).
    • Safely encodes URL query parameters to handle complex addresses.
    • Made usd_fee optional in deserialization to handle API variance.
  • Regression Fix: Ensures native_fee is correctly added to the required storage balance.

Implementation Details:

  • Updated init_transfer in near-bridge-client to accept optional fees.
  • Optimization: Skips the external API call entirely if fees are manually provided.
  • Added reqwest and serde dependencies for API interaction.

Verification & Testing

  • Added test_bridge_indexer_fee_response_parsing unit test for JSON structure verification.
  • Added test_get_transfer_fee_from_indexer integration test using httpmock to simulate realistic API responses and verify client behavior.

I have verified the implementation using:

  1. Unit Tests: Verified JSON deserialization of the indexer response.
  2. Integration Tests: Verified client behavior against a mocked indexer API (using httpmock).
  3. Manual Verification: Verified fallback behavior and CLI configuration overrides.

Note:
If e2e testing is necessary, validation can be done using a live indexer endpoint.

@tom9000 tom9000 force-pushed the feat/auto-calculate-fee branch from 8efab08 to ebf0939 Compare December 18, 2025 20:05
Copy link
Contributor

@frolvanya frolvanya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. Thanks for the contribution!

I know that PR is still in a draft, just decided to mention issues right now, since some of them is easier to fix now instead of the time when all logic for all chains will be ready

Also, we need to calculate fee for init_transfer on every chain (right now it's on near only), therefore instead of duplicating bridge_indexer_api_url for all bridge clients it's better to move whole fee calculation logic to cli's side (I've described reasoning behind this in one of the comments)

@tom9000 tom9000 force-pushed the feat/auto-calculate-fee branch 2 times, most recently from e2d1fa1 to fc3a329 Compare December 20, 2025 09:17
-use U128-typed fees
-early-return on missing indexer URL
-error instead of defaulting on missing transfer fee
-include gas_fee in schema and update tests.

Tests: cargo test -p near-bridge-client --tests; cargo clippy --workspace --all-targets --all-features.

Use shared indexer URL constants for mainnet/testnet/devnet defaults.
@tom9000 tom9000 force-pushed the feat/auto-calculate-fee branch 2 times, most recently from 6f1118e to 8ed0faa Compare December 20, 2025 11:19
- Add bridge-cli/src/fee.rs helper (v3 endpoint, U128-typed fees) and module wiring.
- In NearInitTransfer, fetch fees via indexer when not provided and pass them explicitly; handle missing config/parse/API errors without panicking.
- Keep client-side indexer logic untouched for now.
@tom9000 tom9000 force-pushed the feat/auto-calculate-fee branch from 8ed0faa to 049dc05 Compare December 20, 2025 11:30
- Drop bridge_indexer_api_url, TransferFee DTO, reqwest/dev deps, and get_transfer_fee helper from near-bridge-client.
- Require callers to supply fee/native_fee to init_transfer (error if missing); no HTTP calls in the client.
- Stop passing indexer URL into NearBridgeClient builder in the CLI.
Extends the CLI fee-fetch pattern to EvmInitTransfer, SolanaInitTransfer,
and SolanaInitTransferSol commands. When fees are omitted, the CLI
fetches them from the Bridge Indexer v3 API.

Changes:
- Add derive_evm_sender() to get chain:0x... from configured private key
- Add derive_solana_sender() to get sol:<pubkey> from configured keypair
- Add chain_prefix() returning Result to avoid silent failures
- Add native_fee_to_u64() with overflow check for Solana
- Make fee/native_fee optional for EVM and Solana init commands
- Wire fetch_transfer_fee() with proper error handling (no panics)
- Preserve escape hatch: skip indexer when both fees are provided
- Use sol:So111... for native SOL token address

UTXO gas_fee/protocol_fee wiring deferred to follow-up commit.
Addresses feedback to reduce code duplication in match branches.

Changes:
- Add resolve_near_fees() for Near init transfer fee resolution
- Add resolve_evm_fees() for EVM chains (Eth/Base/Arb/Bnb/Pol)
- Add resolve_solana_fees() for Solana SPL and native SOL transfers
- Inline fetch_fee_quote usage from fee::fetch_transfer_fee
- Each helper returns Result, propagates errors cleanly to call site
- Preserves escape hatch: returns early when both fees are provided
- Match arms now concise single-call + error handling
- Use ChainKind::as_ref() for prefixes
- Rely on OmniAddress::new_from_evm_address for EVM sender/token strings.
- Rename/document solana_native_fee_to_u64 to make the Solana-only downcast explicit and error on overflow.
…Request struct and NativeFeeConversion enum were added to satisfy clippy "too many args".

- Add message plumbing for Near init transfers, so UTXO gas/protocol fee payloads can be passed through
- Remove `pub` from `utxo_bridges` field in NearBridgeClient for encapsulation
- Replace generic `resolve_fees` with simpler `fetch_indexer_fees` helper
- Remove `FeeRequest` struct, `NativeFeeConversion` enum, and closures
- Move fee branching logic (manual vs auto) to call sites for clarity
- Chain-specific wrappers (`resolve_evm_fees`, `resolve_solana_fees`) now
  call `fetch_indexer_fees` directly and handle type conversions
- Require both `fee` and `native_fee` for manual mode; error on partial input
Copy link
Contributor

@frolvanya frolvanya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix CI as well

let (fee, native_fee, gas_fee) = match (fee, native_fee) {
(Some(f), Some(nf)) => (f, nf, None),
(Some(_), None) | (None, Some(_)) => {
eprintln!("Both fee and native_fee must be provided to skip indexer calculation");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's incorrect. Transfers need only one type of fee: either transferred fee or native fee, so we don't need to provide both

Copy link
Contributor Author

@tom9000 tom9000 Jan 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I see. Relaxed requirements to allow either --fee or --native-fee independently. And set the other one to 0.

tom9000 added a commit to tom9000/bridge-sdk-rs that referenced this pull request Jan 15, 2026
- Unified TransferFeeDto and FeeQuote into a single TransferFee struct using near-sdk compatible U128 types.
- Relaxed fee requirements for init-transfer commands to allow providing either --fee or --native-fee independently. Empty values set to 0.
- Refactored derive_evm_sender to utilize the evm_address_to_omni helper for address derivation.
- Cleaned up unused usd_fee code and resolved clippy warnings for inlined format arguments.
@tom9000
Copy link
Contributor Author

tom9000 commented Jan 16, 2026

Please fix CI as well
I believe everything is fixed now. There is an issue with eth-proof but it seems to be coming from the RPC, so I guess it should fix itself. Please let me know if more of a fix is needed.

@frolvanya frolvanya marked this pull request as ready for review January 16, 2026 11:42
@frolvanya frolvanya requested a review from a team January 16, 2026 11:42
@frolvanya frolvanya requested a review from kiseln January 16, 2026 11:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bridge-sdk-rs]: Automatically calculate the required fee when initiating a transfer.

3 participants