/ docs / Documentation.md
Documentation.md
   1  # f(x) Protocol Python SDK - Complete Documentation
   2  
   3  **Version:** 0.3.0  
   4  **Creator:** Christopher Stampar (@cstampar)  
   5  **Last Updated:** December 22, 2025
   6  
   7  ---
   8  
   9  ## Table of Contents
  10  
  11  1. [Introduction](#introduction)
  12  2. [Installation](#installation)
  13  3. [Quick Start](#quick-start)
  14  4. [Authentication](#authentication)
  15  5. [Core Classes](#core-classes)
  16  6. [Token Balance Methods](#token-balance-methods)
  17  7. [V1 Protocol Methods](#v1-protocol-methods)
  18  8. [V2 Protocol Methods](#v2-protocol-methods)
  19  9. [Governance Methods](#governance-methods)
  20  10. [Convex Finance Integration](#convex-finance-integration)
  21  11. [Curve Finance Integration](#curve-finance-integration)
  22  12. [Utility Methods](#utility-methods)
  23  13. [Error Handling](#error-handling)
  24  14. [Examples](#examples)
  25  
  26  ---
  27  
  28  ## Introduction
  29  
  30  The f(x) Protocol Python SDK provides a production-grade interface for interacting with the f(x) Protocol on Ethereum. It abstracts Web3.py boilerplate and provides human-readable interfaces for both V1 and V2 products, including Convex Finance and Curve Finance integrations.
  31  
  32  ### Key Features
  33  
  34  - **High-Precision**: Uses Python `Decimal` for all amounts to prevent floating-point errors
  35  - **Secure Authentication**: Multiple secure credential sources (env vars, .env files, Colab secrets, browser wallets)
  36  - **Read-Only Mode**: Full querying capabilities without private keys
  37  - **Comprehensive Coverage**: V1, V2, Convex, and Curve Finance integrations
  38  - **Production-Ready**: Robust error handling, logging, and type hints
  39  
  40  ---
  41  
  42  ## Installation
  43  
  44  ```bash
  45  pip install fx-sdk
  46  ```
  47  
  48  ### Requirements
  49  
  50  - Python >= 3.8
  51  - Web3.py >= 6.0.0
  52  - eth-account >= 0.5.0
  53  
  54  ---
  55  
  56  ## Quick Start
  57  
  58  ### Read-Only Mode (No Private Key)
  59  
  60  ```python
  61  from fx_sdk.client import ProtocolClient
  62  
  63  client = ProtocolClient(
  64      rpc_url="https://eth.llamarpc.com"
  65  )
  66  
  67  # Get fxUSD balance for any address
  68  balance = client.get_fxusd_balance("0x1234...")
  69  print(f"fxUSD Balance: {balance}")
  70  ```
  71  
  72  ### Write Mode (With Authentication)
  73  
  74  ```python
  75  from fx_sdk.client import ProtocolClient
  76  
  77  # Private key loaded from environment variable
  78  client = ProtocolClient(
  79      rpc_url="https://eth.llamarpc.com"
  80  )
  81  
  82  # Mint fxUSD
  83  tx_hash = client.mint_f_token(
  84      market_address="0x...",
  85      base_in=1.0
  86  )
  87  print(f"Transaction: {tx_hash}")
  88  ```
  89  
  90  ---
  91  
  92  ## Authentication
  93  
  94  The SDK supports multiple secure authentication methods. **Never hardcode private keys in your code!**
  95  
  96  ### Priority Order
  97  
  98  1. Explicit `private_key` parameter (lowest priority, for testing only)
  99  2. `FX_PROTOCOL_PRIVATE_KEY` environment variable
 100  3. `.env` file (`FX_PROTOCOL_PRIVATE_KEY`)
 101  4. Google Colab secret (`fx_protocol_private_key`)
 102  5. Browser wallet (if `use_browser_wallet=True`)
 103  
 104  ### Environment Variable
 105  
 106  ```bash
 107  export FX_PROTOCOL_PRIVATE_KEY="0x..."
 108  ```
 109  
 110  ```python
 111  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
 112  ```
 113  
 114  ### .env File
 115  
 116  Create `.env`:
 117  ```
 118  FX_PROTOCOL_PRIVATE_KEY=0x...
 119  ```
 120  
 121  ```python
 122  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
 123  ```
 124  
 125  ### Google Colab
 126  
 127  ```python
 128  # Store secret in Colab: 'fx_protocol_private_key'
 129  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
 130  ```
 131  
 132  ### Browser Wallet
 133  
 134  ```python
 135  client = ProtocolClient(
 136      rpc_url="https://eth.llamarpc.com",
 137      use_browser_wallet=True
 138  )
 139  ```
 140  
 141  ---
 142  
 143  ## Core Classes
 144  
 145  ### ProtocolClient
 146  
 147  The main client class for interacting with the f(x) Protocol.
 148  
 149  #### Initialization
 150  
 151  ```python
 152  ProtocolClient(
 153      rpc_url: str,
 154      private_key: Optional[str] = None,
 155      abi_dir: Optional[str] = None,
 156      log_level: int = logging.INFO,
 157      use_browser_wallet: bool = False
 158  )
 159  ```
 160  
 161  **Parameters:**
 162  - `rpc_url` (str): Ethereum RPC endpoint URL
 163  - `private_key` (Optional[str]): Private key (not recommended, use env vars)
 164  - `abi_dir` (Optional[str]): Custom ABI directory (defaults to package ABIs)
 165  - `log_level` (int): Logging level (default: `logging.INFO`)
 166  - `use_browser_wallet` (bool): Connect to browser wallet (default: `False`)
 167  
 168  **Example:**
 169  ```python
 170  client = ProtocolClient(
 171      rpc_url="https://eth.llamarpc.com",
 172      log_level=logging.DEBUG
 173  )
 174  ```
 175  
 176  ---
 177  
 178  
 179  ## Token Balance Methods
 180  
 181  ### Generic Token Methods
 182  
 183  #### `get_token_balance(token_address, account_address=None)`
 184  
 185  Get the human-readable balance of any ERC-20 token.
 186  
 187  **Parameters:**
 188  - `token_address` (str): ERC-20 token contract address
 189  - `account_address` (Optional[str]): Account address (defaults to client's address)
 190  
 191  **Returns:** `Decimal` - Human-readable token balance
 192  
 193  **Example:**
 194  ```python
 195  balance = client.get_token_balance(
 196      token_address="0x085780639CC2cACd35E474e71f4d000e2405d8f6",
 197      account_address="0x1234..."
 198  )
 199  print(f"Balance: {balance}")
 200  ```
 201  
 202  #### `get_token_total_supply(token_address)`
 203  
 204  Get the total supply of a token.
 205  
 206  **Parameters:**
 207  - `token_address` (str): Token contract address
 208  
 209  **Returns:** `Decimal` - Total supply
 210  
 211  #### `get_allowance(token_address, owner, spender)`
 212  
 213  Get the allowance of a spender for a token owner.
 214  
 215  **Parameters:**
 216  - `token_address` (str): Token contract address
 217  - `owner` (str): Token owner address
 218  - `spender` (str): Spender address
 219  
 220  **Returns:** `Decimal` - Allowance amount
 221  
 222  ### Protocol Token Balance Methods
 223  
 224  All methods follow the same pattern: `get_{token}_balance(account_address=None)`
 225  
 226  **Available Methods:**
 227  - `get_fxusd_balance()` - fxUSD balance
 228  - `get_feth_balance()` - fETH balance
 229  - `get_rusd_balance()` - rUSD balance
 230  - `get_btcusd_balance()` - btcUSD balance
 231  - `get_cvxusd_balance()` - cvxUSD balance
 232  - `get_arusd_balance()` - arUSD balance
 233  - `get_xeth_balance()` - xETH balance
 234  - `get_xcvx_balance()` - xCVX balance
 235  - `get_xwbtc_balance()` - xWBTC balance
 236  - `get_xeeth_balance()` - xeETH balance
 237  - `get_xezeth_balance()` - xezETH balance
 238  - `get_xsteth_balance()` - xstETH balance
 239  - `get_xfrxeth_balance()` - xfrxETH balance
 240  - `get_fxsave_balance()` - fxSAVE balance
 241  - `get_fxsp_balance()` - fxSP balance
 242  - `get_fxn_balance()` - FXN balance
 243  - `get_vefxn_balance()` - veFXN balance
 244  - `get_cvxfxn_balance()` - cvxFXN balance
 245  
 246  **Example:**
 247  ```python
 248  fxusd = client.get_fxusd_balance()
 249  feth = client.get_feth_balance()
 250  print(f"fxUSD: {fxusd}, fETH: {feth}")
 251  ```
 252  
 253  #### `get_all_balances(account_address=None)`
 254  
 255  Get all protocol token balances in a single call.
 256  
 257  **Returns:** `Dict[str, Decimal]` - Dictionary mapping token names to balances
 258  
 259  **Example:**
 260  ```python
 261  balances = client.get_all_balances("0x1234...")
 262  for token, balance in balances.items():
 263      print(f"{token}: {balance}")
 264  ```
 265  
 266  ---
 267  
 268  ## V1 Protocol Methods
 269  
 270  ### Market Information
 271  
 272  #### `get_v1_nav()`
 273  
 274  Get Net Asset Value (NAV) for V1 fETH and xETH.
 275  
 276  **Returns:** `Dict[str, Decimal]` with keys:
 277  - `fETH_NAV`: fETH Net Asset Value
 278  - `xETH_NAV`: xETH Net Asset Value
 279  
 280  #### `get_v1_collateral_ratio()`
 281  
 282  Get the current collateral ratio of the V1 market.
 283  
 284  **Returns:** `Decimal` - Collateral ratio
 285  
 286  ### Rebalance Pools
 287  
 288  #### `get_v1_rebalance_pools()`
 289  
 290  Get all registered V1 rebalance pool addresses.
 291  
 292  **Returns:** `List[str]` - List of pool addresses
 293  
 294  #### `get_v1_rebalance_pool_balances(pool_address, account_address=None)`
 295  
 296  Get balances for an account in a V1 rebalance pool.
 297  
 298  **Parameters:**
 299  - `pool_address` (str): Rebalance pool address
 300  - `account_address` (Optional[str]): Account address
 301  
 302  **Returns:** `Dict[str, Decimal]` with keys:
 303  - `staked`: Staked balance
 304  - `unlocked`: Unlocked balance
 305  - `unlocking`: Balance currently unlocking
 306  
 307  ### V1 Treasury Operations
 308  
 309  #### `mint_via_treasury(base_in, recipient=None, option=0)`
 310  
 311  Mint fETH and xETH via the V1 Treasury.
 312  
 313  **Parameters:**
 314  - `base_in` (Union[int, float, Decimal, str]): Amount of base token (stETH) to deposit
 315  - `recipient` (Optional[str]): Recipient address (defaults to client address)
 316  - `option` (int): Minting option (0 = default)
 317  
 318  **Returns:** `str` - Transaction hash
 319  
 320  **Example:**
 321  ```python
 322  tx_hash = client.mint_via_treasury(base_in=1.0)
 323  print(f"Minted via treasury: {tx_hash}")
 324  ```
 325  
 326  #### `redeem_via_treasury(f_token_in=0, x_token_in=0, owner=None)`
 327  
 328  Redeem fETH and/or xETH via the V1 Treasury.
 329  
 330  **Parameters:**
 331  - `f_token_in` (Union[int, float, Decimal, str]): Amount of f-token to redeem
 332  - `x_token_in` (Union[int, float, Decimal, str]): Amount of x-token to redeem
 333  - `owner` (Optional[str]): Owner address (defaults to client address)
 334  
 335  **Returns:** `str` - Transaction hash
 336  
 337  ---
 338  
 339  ## V2 Protocol Methods
 340  
 341  ### Pool Information
 342  
 343  #### `get_v2_pool_info()`
 344  
 345  Get information about the V2 fxUSD Base Pool.
 346  
 347  **Returns:** `Dict[str, Any]` with pool information
 348  
 349  #### `get_steth_price()`
 350  
 351  Get the current stETH price from the oracle.
 352  
 353  **Returns:** `Decimal` - stETH price
 354  
 355  #### `get_fxusd_total_supply()`
 356  
 357  Get the total supply of fxUSD.
 358  
 359  **Returns:** `Decimal` - Total fxUSD supply
 360  
 361  ### V2 Position Management
 362  
 363  #### `operate_position(pool_address, position_id, new_collateral, new_debt)`
 364  
 365  Operate (modify) a V2 position.
 366  
 367  **Parameters:**
 368  - `pool_address` (str): Pool address
 369  - `position_id` (int): Position ID
 370  - `new_collateral` (Union[int, float, Decimal, str]): New collateral amount
 371  - `new_debt` (Union[int, float, Decimal, str]): New debt amount
 372  
 373  **Returns:** `str` - Transaction hash
 374  
 375  #### `rebalance_position(pool_address, receiver, position_id, max_fxusd, max_stable)`
 376  
 377  Rebalance a V2 position.
 378  
 379  **Parameters:**
 380  - `pool_address` (str): Pool address
 381  - `receiver` (str): Receiver address
 382  - `position_id` (int): Position ID
 383  - `max_fxusd` (Union[int, float, Decimal, str]): Maximum fxUSD to use
 384  - `max_stable` (Union[int, float, Decimal, str]): Maximum stable token to use
 385  
 386  **Returns:** `str` - Transaction hash
 387  
 388  #### `liquidate_position(pool_address, receiver, position_id, max_fxusd, max_stable)`
 389  
 390  Liquidate a V2 position.
 391  
 392  **Parameters:**
 393  - `pool_address` (str): Pool address
 394  - `receiver` (str): Receiver address
 395  - `position_id` (int): Position ID
 396  - `max_fxusd` (Union[int, float, Decimal, str]): Maximum fxUSD to use
 397  - `max_stable` (Union[int, float, Decimal, str]): Maximum stable token to use
 398  
 399  **Returns:** `str` - Transaction hash
 400  
 401  #### `get_position_info(position_id)`
 402  
 403  Get information about a V2 position.
 404  
 405  **Parameters:**
 406  - `position_id` (int): Position ID
 407  
 408  **Returns:** `Dict[str, Any]` - Position information
 409  
 410  ### V2 Minting & Redeeming
 411  
 412  #### `mint_f_token(market_address, base_in, recipient=None, min_f_token_out=0)`
 413  
 414  Mint f-token (e.g., fxUSD) from base token.
 415  
 416  **Parameters:**
 417  - `market_address` (str): Market contract address
 418  - `base_in` (Union[int, float, Decimal, str]): Amount of base token to deposit
 419  - `recipient` (Optional[str]): Recipient address
 420  - `min_f_token_out` (Union[int, float, Decimal, str]): Minimum f-token output (slippage protection)
 421  
 422  **Returns:** `str` - Transaction hash
 423  
 424  **Example:**
 425  ```python
 426  tx_hash = client.mint_f_token(
 427      market_address="0x...",
 428      base_in=1.0,
 429      min_f_token_out=0.99
 430  )
 431  ```
 432  
 433  #### `mint_x_token(market_address, base_in, recipient=None, min_x_token_out=0)`
 434  
 435  Mint x-token from base token.
 436  
 437  **Parameters:**
 438  - `market_address` (str): Market contract address
 439  - `base_in` (Union[int, float, Decimal, str]): Amount of base token to deposit
 440  - `recipient` (Optional[str]): Recipient address
 441  - `min_x_token_out` (Union[int, float, Decimal, str]): Minimum x-token output
 442  
 443  **Returns:** `str` - Transaction hash
 444  
 445  #### `mint_both_tokens(market_address, base_in, recipient=None, min_f_token_out=0, min_x_token_out=0)`
 446  
 447  Mint both f-token and x-token simultaneously.
 448  
 449  **Parameters:**
 450  - `market_address` (str): Market contract address
 451  - `base_in` (Union[int, float, Decimal, str]): Amount of base token to deposit
 452  - `recipient` (Optional[str]): Recipient address
 453  - `min_f_token_out` (Union[int, float, Decimal, str]): Minimum f-token output
 454  - `min_x_token_out` (Union[int, float, Decimal, str]): Minimum x-token output
 455  
 456  **Returns:** `str` - Transaction hash
 457  
 458  #### `redeem(market_address, f_token_in=0, x_token_in=0, recipient=None, min_base_out=0)`
 459  
 460  Redeem f-token and/or x-token for base token.
 461  
 462  **Parameters:**
 463  - `market_address` (str): Market contract address
 464  - `f_token_in` (Union[int, float, Decimal, str]): Amount of f-token to redeem
 465  - `x_token_in` (Union[int, float, Decimal, str]): Amount of x-token to redeem
 466  - `recipient` (Optional[str]): Recipient address
 467  - `min_base_out` (Union[int, float, Decimal, str]): Minimum base token output
 468  
 469  **Returns:** `str` - Transaction hash
 470  
 471  ### Stability Pool & Savings
 472  
 473  #### `deposit_to_stability_pool(amount)`
 474  
 475  Deposit to the fxUSD Stability Pool.
 476  
 477  **Parameters:**
 478  - `amount` (Union[int, float, Decimal, str]): Amount of fxUSD to deposit
 479  
 480  **Returns:** `str` - Transaction hash
 481  
 482  #### `withdraw_from_stability_pool(amount)`
 483  
 484  Withdraw from the fxUSD Stability Pool.
 485  
 486  **Parameters:**
 487  - `amount` (Union[int, float, Decimal, str]): Amount to withdraw
 488  
 489  **Returns:** `str` - Transaction hash
 490  
 491  #### `deposit_fxsave(amount)`
 492  
 493  Deposit to fxSAVE (Saving fxUSD).
 494  
 495  **Parameters:**
 496  - `amount` (Union[int, float, Decimal, str]): Amount of fxUSD to deposit
 497  
 498  **Returns:** `str` - Transaction hash
 499  
 500  #### `redeem_fxsave(amount)`
 501  
 502  Redeem from fxSAVE.
 503  
 504  **Parameters:**
 505  - `amount` (Union[int, float, Decimal, str]): Amount to redeem
 506  
 507  **Returns:** `str` - Transaction hash
 508  
 509  ---
 510  
 511  
 512  ## Governance Methods
 513  
 514  ### veFXN Staking
 515  
 516  #### `deposit_to_vefxn(amount, unlock_time)`
 517  
 518  Lock FXN to create veFXN (vote-escrowed FXN).
 519  
 520  **Parameters:**
 521  - `amount` (Union[int, float, Decimal, str]): Amount of FXN to lock
 522  - `unlock_time` (int): Unix timestamp when lock expires
 523  
 524  **Returns:** `str` - Transaction hash
 525  
 526  **Example:**
 527  ```python
 528  import time
 529  # Lock for 1 year
 530  unlock_time = int(time.time()) + (365 * 24 * 60 * 60)
 531  tx_hash = client.deposit_to_vefxn(amount=1000, unlock_time=unlock_time)
 532  ```
 533  
 534  #### `get_vefxn_locked_info(account_address=None)`
 535  
 536  Get locked FXN information for an account.
 537  
 538  **Returns:** `Dict[str, Any]` with keys:
 539  - `amount`: Locked FXN amount
 540  - `end`: Unlock timestamp
 541  
 542  ### Gauge Voting
 543  
 544  #### `vote_for_gauge_weight(gauge_address, user_weight)`
 545  
 546  Vote for a gauge's weight allocation.
 547  
 548  **Parameters:**
 549  - `gauge_address` (str): Gauge contract address
 550  - `user_weight` (int): Weight to allocate (0-10000, where 10000 = 100%)
 551  
 552  **Returns:** `str` - Transaction hash
 553  
 554  **Example:**
 555  ```python
 556  # Allocate 50% of voting power to a gauge
 557  tx_hash = client.vote_for_gauge_weight(
 558      gauge_address="0x...",
 559      user_weight=5000
 560  )
 561  ```
 562  
 563  #### `get_gauge_weight(gauge_address)`
 564  
 565  Get the absolute weight of a gauge.
 566  
 567  **Returns:** `Decimal` - Gauge weight
 568  
 569  #### `get_gauge_relative_weight(gauge_address)`
 570  
 571  Get the relative weight of a gauge (0-1).
 572  
 573  **Returns:** `Decimal` - Relative weight
 574  
 575  ### Gauge Rewards
 576  
 577  #### `claim_gauge_rewards(gauge_address, account=None)`
 578  
 579  Claim rewards from a specific gauge.
 580  
 581  **Parameters:**
 582  - `gauge_address` (str): Gauge contract address
 583  - `account` (Optional[str]): Account address (defaults to client address)
 584  
 585  **Returns:** `str` - Transaction hash
 586  
 587  #### `claim_all_gauge_rewards()`
 588  
 589  Claim rewards from all gauges where the user has staked.
 590  
 591  **Returns:** `List[str]` - List of transaction hashes
 592  
 593  **Example:**
 594  ```python
 595  tx_hashes = client.claim_all_gauge_rewards()
 596  print(f"Claimed from {len(tx_hashes)} gauges")
 597  ```
 598  
 599  #### `get_claimable_rewards(gauge_address, token_address, account_address=None)`
 600  
 601  Get claimable rewards for a specific token from a gauge.
 602  
 603  **Parameters:**
 604  - `gauge_address` (str): Gauge contract address
 605  - `token_address` (str): Reward token address
 606  - `account_address` (Optional[str]): Account address
 607  
 608  **Returns:** `Decimal` - Claimable reward amount
 609  
 610  #### `get_all_gauge_balances(account_address=None)`
 611  
 612  Get all gauge staked balances for an account.
 613  
 614  **Returns:** `Dict[str, Decimal]` - Dictionary mapping gauge addresses to staked amounts
 615  
 616  ### Vesting
 617  
 618  #### `claim_fxn_vesting()`
 619  
 620  Claim vested FXN tokens.
 621  
 622  **Returns:** `str` - Transaction hash
 623  
 624  #### `claim_feth_vesting()`
 625  
 626  Claim vested fETH tokens.
 627  
 628  **Returns:** `str` - Transaction hash
 629  
 630  #### `claim_fxusd_vesting()`
 631  
 632  Claim vested fxUSD tokens.
 633  
 634  **Returns:** `str` - Transaction hash
 635  
 636  ---
 637  
 638  ## Convex Finance Integration
 639  
 640  The SDK provides comprehensive integration with Convex Finance for f(x) Protocol pools. Convex vaults are user-specific contracts that allow staking LP tokens and claiming rewards.
 641  
 642  ### Vault Management
 643  
 644  #### `create_convex_vault(pool_id)`
 645  
 646  Create a new Convex vault for a specific pool.
 647  
 648  **Parameters:**
 649  - `pool_id` (int): Convex pool ID
 650  
 651  **Returns:** `Dict[str, Any]` with keys:
 652  - `vault_address`: Created vault address
 653  - `tx_hash`: Transaction hash
 654  - `pool_id`: Pool ID
 655  
 656  **Example:**
 657  ```python
 658  result = client.create_convex_vault(pool_id=37)
 659  print(f"Vault created: {result['vault_address']}")
 660  ```
 661  
 662  #### `get_convex_vault_address(wallet_address, pool_id)`
 663  
 664  Get the vault address for a wallet and pool ID.
 665  
 666  **Parameters:**
 667  - `wallet_address` (str): Wallet address
 668  - `pool_id` (int): Convex pool ID
 669  
 670  **Returns:** `Optional[str]` - Vault address if exists, None otherwise
 671  
 672  #### `get_convex_vault_address_or_create(pool_id)`
 673  
 674  Get existing vault address or create a new one.
 675  
 676  **Parameters:**
 677  - `pool_id` (int): Convex pool ID
 678  
 679  **Returns:** `str` - Vault address
 680  
 681  #### `get_convex_vault_address_from_tx(tx_hash)`
 682  
 683  Extract vault address from a createVault transaction.
 684  
 685  **Parameters:**
 686  - `tx_hash` (str): Transaction hash from `create_convex_vault()`
 687  
 688  **Returns:** `Optional[str]` - Vault address if found
 689  
 690  ### Vault Operations
 691  
 692  #### `deposit_to_convex_vault(vault_address, amount, manage=False)`
 693  
 694  Deposit LP tokens to a Convex vault.
 695  
 696  **Parameters:**
 697  - `vault_address` (str): User's vault address
 698  - `amount` (Union[int, float, Decimal, str]): Amount of LP tokens to deposit
 699  - `manage` (bool): Whether to manage the deposit (auto-stake)
 700  
 701  **Returns:** `str` - Transaction hash
 702  
 703  **Example:**
 704  ```python
 705  tx_hash = client.deposit_to_convex_vault(
 706      vault_address="0x...",
 707      amount=100.0
 708  )
 709  ```
 710  
 711  #### `withdraw_from_convex_vault(vault_address, amount)`
 712  
 713  Withdraw LP tokens from a Convex vault.
 714  
 715  **Parameters:**
 716  - `vault_address` (str): User's vault address
 717  - `amount` (Union[int, float, Decimal, str]): Amount to withdraw
 718  
 719  **Returns:** `str` - Transaction hash
 720  
 721  #### `claim_convex_vault_rewards(vault_address, claim=True, token_list=None)`
 722  
 723  Claim rewards from a Convex vault.
 724  
 725  **Parameters:**
 726  - `vault_address` (str): User's vault address
 727  - `claim` (bool): Whether to claim rewards
 728  - `token_list` (Optional[List[str]]): Specific tokens to claim (None = all)
 729  
 730  **Returns:** `str` - Transaction hash
 731  
 732  ### Vault Queries (Read-Only)
 733  
 734  #### `get_convex_vault_balance(vault_address, token_address=None)`
 735  
 736  Get staked balance in a Convex vault.
 737  
 738  **Parameters:**
 739  - `vault_address` (str): User's vault address
 740  - `token_address` (Optional[str]): Token address (optional)
 741  
 742  **Returns:** `Decimal` - Staked balance
 743  
 744  #### `get_convex_vault_rewards(vault_address)`
 745  
 746  Get claimable rewards for a Convex vault.
 747  
 748  **Parameters:**
 749  - `vault_address` (str): User's vault address
 750  
 751  **Returns:** `Dict[str, Any]` with keys:
 752  - `token_addresses`: List of reward token addresses
 753  - `amounts`: Dictionary mapping token addresses to claimable amounts
 754  
 755  **Example:**
 756  ```python
 757  rewards = client.get_convex_vault_rewards("0x...")
 758  for token, amount in rewards['amounts'].items():
 759      print(f"{token}: {amount}")
 760  ```
 761  
 762  #### `get_convex_vault_info(vault_address)`
 763  
 764  Get information about a Convex vault.
 765  
 766  **Parameters:**
 767  - `vault_address` (str): User's vault address
 768  
 769  **Returns:** `Dict[str, Any]` with keys:
 770  - `owner`: Vault owner address
 771  - `pid`: Pool ID
 772  - `staking_token`: Staking token address
 773  - `gauge_address`: Gauge address
 774  - `rewards`: Rewards contract address
 775  
 776  ### cvxFXN Staking
 777  
 778  #### `deposit_fxn_to_cvxfxn(amount)`
 779  
 780  Convert FXN to cvxFXN.
 781  
 782  **Parameters:**
 783  - `amount` (Union[int, float, Decimal, str]): Amount of FXN to convert
 784  
 785  **Returns:** `str` - Transaction hash
 786  
 787  #### `stake_cvxfxn(amount)`
 788  
 789  Stake cvxFXN tokens for additional rewards.
 790  
 791  **Parameters:**
 792  - `amount` (Union[int, float, Decimal, str]): Amount of cvxFXN to stake
 793  
 794  **Returns:** `str` - Transaction hash
 795  
 796  #### `unstake_cvxfxn(amount)`
 797  
 798  Unstake cvxFXN tokens.
 799  
 800  **Parameters:**
 801  - `amount` (Union[int, float, Decimal, str]): Amount to unstake
 802  
 803  **Returns:** `str` - Transaction hash
 804  
 805  #### `claim_cvxfxn_staking_rewards()`
 806  
 807  Claim cvxFXN staking rewards.
 808  
 809  **Returns:** `str` - Transaction hash
 810  
 811  #### `get_cvxfxn_balance(account_address=None)`
 812  
 813  Get cvxFXN token balance.
 814  
 815  **Returns:** `Decimal` - cvxFXN balance
 816  
 817  #### `get_staked_cvxfxn_balance(account_address=None)`
 818  
 819  Get staked cvxFXN balance.
 820  
 821  **Returns:** `Decimal` - Staked balance
 822  
 823  #### `get_cvxfxn_staking_rewards(account_address=None)`
 824  
 825  Get claimable cvxFXN staking rewards.
 826  
 827  **Returns:** `Dict[str, Decimal]` - Reward token addresses to amounts
 828  
 829  #### `get_cvxfxn_staking_info()`
 830  
 831  Get cvxFXN staking information (reward rate, period finish, etc.).
 832  
 833  **Returns:** `Dict[str, Any]` - Staking information
 834  
 835  ### Helper Methods
 836  
 837  #### `get_all_user_vaults(wallet_address)`
 838  
 839  Discover all vault addresses for a user across all pools.
 840  
 841  **Parameters:**
 842  - `wallet_address` (str): Wallet address
 843  
 844  **Returns:** `List[str]` - List of vault addresses
 845  
 846  #### `get_convex_pool_info(pool_id=None, pool_key=None)`
 847  
 848  Get pool information by ID or key.
 849  
 850  **Parameters:**
 851  - `pool_id` (Optional[int]): Pool ID
 852  - `pool_key` (Optional[str]): Pool key (e.g., "fxusd_v2_stability_fxn")
 853  
 854  **Returns:** `Dict[str, Any]` - Pool information
 855  
 856  #### `get_all_convex_pools()`
 857  
 858  Get all registered Convex pools.
 859  
 860  **Returns:** `Dict[str, Dict[str, Any]]` - Dictionary of pool keys to pool information
 861  
 862  #### `get_vault_balances_batch(vault_addresses)`
 863  
 864  Query multiple vault balances efficiently.
 865  
 866  **Parameters:**
 867  - `vault_addresses` (List[str]): List of vault addresses
 868  
 869  **Returns:** `Dict[str, Decimal]` - Dictionary mapping vault addresses to balances
 870  
 871  #### `get_vault_rewards_batch(vault_addresses)`
 872  
 873  Query multiple vault rewards efficiently.
 874  
 875  **Parameters:**
 876  - `vault_addresses` (List[str]): List of vault addresses
 877  
 878  **Returns:** `Dict[str, Dict[str, Any]]` - Dictionary mapping vault addresses to rewards
 879  
 880  #### `get_user_vaults_summary(wallet_address)`
 881  
 882  Get comprehensive overview of all user vaults.
 883  
 884  **Parameters:**
 885  - `wallet_address` (str): Wallet address
 886  
 887  **Returns:** `Dict[str, Any]` - Summary with balances and rewards for all vaults
 888  
 889  ---
 890  
 891  
 892  ## Curve Finance Integration
 893  
 894  The SDK provides comprehensive integration with Curve Finance for swapping, liquidity management, and gauge staking.
 895  
 896  ### Pool Information
 897  
 898  #### `get_curve_pool_info(pool_address)`
 899  
 900  Get comprehensive information about a Curve pool.
 901  
 902  **Parameters:**
 903  - `pool_address` (str): Curve pool address
 904  
 905  **Returns:** `Dict[str, Any]` with keys:
 906  - `coins`: List of coin addresses
 907  - `balances`: List of coin balances
 908  - `virtual_price`: Virtual price
 909  - `lp_token`: LP token address
 910  
 911  #### `find_curve_pool(token_a, token_b)`
 912  
 913  Find a Curve pool by token pair.
 914  
 915  **Parameters:**
 916  - `token_a` (str): First token address
 917  - `token_b` (str): Second token address
 918  
 919  **Returns:** `Optional[str]` - Pool address if found
 920  
 921  #### `get_curve_pool_from_lp_token(lp_token_address)`
 922  
 923  Find a Curve pool from its LP token address.
 924  
 925  **Parameters:**
 926  - `lp_token_address` (str): LP token address
 927  
 928  **Returns:** `Optional[str]` - Pool address if found
 929  
 930  #### `get_curve_pool_balances(pool_address)`
 931  
 932  Get current balances for all coins in a Curve pool.
 933  
 934  **Parameters:**
 935  - `pool_address` (str): Curve pool address
 936  
 937  **Returns:** `List[Decimal]` - List of coin balances
 938  
 939  #### `get_curve_pool_virtual_price(pool_address)`
 940  
 941  Get the virtual price of a Curve pool.
 942  
 943  **Parameters:**
 944  - `pool_address` (str): Curve pool address
 945  
 946  **Returns:** `Decimal` - Virtual price
 947  
 948  #### `get_curve_swap_rate(pool_address, token_in, token_out, amount_in)`
 949  
 950  Calculate the output amount for a swap before executing.
 951  
 952  **Parameters:**
 953  - `pool_address` (str): Curve pool address
 954  - `token_in` (str): Input token address
 955  - `token_out` (str): Output token address
 956  - `amount_in` (Union[int, float, Decimal, str]): Input amount
 957  
 958  **Returns:** `Decimal` - Expected output amount
 959  
 960  ### Swap Operations
 961  
 962  #### `curve_swap(pool_address, token_in, token_out, amount_in, min_amount_out=None)`
 963  
 964  Execute a token swap on Curve.
 965  
 966  **Parameters:**
 967  - `pool_address` (str): Curve pool address
 968  - `token_in` (str): Input token address
 969  - `token_out` (str): Output token address
 970  - `amount_in` (Union[int, float, Decimal, str]): Input amount
 971  - `min_amount_out` (Optional[Union[int, float, Decimal, str]]): Minimum output (slippage protection, default 0.5%)
 972  
 973  **Returns:** `str` - Transaction hash
 974  
 975  **Example:**
 976  ```python
 977  tx_hash = client.curve_swap(
 978      pool_address="0x...",
 979      token_in="0x085780639CC2cACd35E474e71f4d000e2405d8f6",  # fxUSD
 980      token_out="0x...",  # USDC
 981      amount_in=1000.0,
 982      min_amount_out=995.0  # 0.5% slippage
 983  )
 984  ```
 985  
 986  ### Liquidity Management
 987  
 988  #### `curve_add_liquidity(pool_address, amounts, min_lp_tokens=None)`
 989  
 990  Add liquidity to a Curve pool.
 991  
 992  **Parameters:**
 993  - `pool_address` (str): Curve pool address
 994  - `amounts` (List[Union[int, float, Decimal, str]]): Amounts for each coin
 995  - `min_lp_tokens` (Optional[Union[int, float, Decimal, str]]): Minimum LP tokens (slippage protection)
 996  
 997  **Returns:** `str` - Transaction hash
 998  
 999  **Example:**
1000  ```python
1001  tx_hash = client.curve_add_liquidity(
1002      pool_address="0x...",
1003      amounts=[1000.0, 1000.0],  # 2-coin pool
1004      min_lp_tokens=1990.0
1005  )
1006  ```
1007  
1008  #### `curve_remove_liquidity(pool_address, lp_token_amount, min_amounts=None)`
1009  
1010  Remove liquidity from a Curve pool.
1011  
1012  **Parameters:**
1013  - `pool_address` (str): Curve pool address
1014  - `lp_token_amount` (Union[int, float, Decimal, str]): Amount of LP tokens to burn
1015  - `min_amounts` (Optional[List[Union[int, float, Decimal, str]]]): Minimum amounts for each coin
1016  
1017  **Returns:** `str` - Transaction hash
1018  
1019  ### Gauge Staking
1020  
1021  #### `get_curve_gauge_info(gauge_address)`
1022  
1023  Get information about a Curve gauge.
1024  
1025  **Parameters:**
1026  - `gauge_address` (str): Gauge contract address
1027  
1028  **Returns:** `Dict[str, Any]` - Gauge information
1029  
1030  #### `curve_stake_lp_tokens(gauge_address, lp_token_amount)`
1031  
1032  Stake LP tokens in a Curve gauge to earn CRV rewards.
1033  
1034  **Parameters:**
1035  - `gauge_address` (str): Gauge contract address
1036  - `lp_token_amount` (Union[int, float, Decimal, str]): Amount of LP tokens to stake
1037  
1038  **Returns:** `str` - Transaction hash
1039  
1040  #### `curve_unstake_lp_tokens(gauge_address, lp_token_amount, claim_rewards=False)`
1041  
1042  Unstake LP tokens from a Curve gauge.
1043  
1044  **Parameters:**
1045  - `gauge_address` (str): Gauge contract address
1046  - `lp_token_amount` (Union[int, float, Decimal, str]): Amount to unstake
1047  - `claim_rewards` (bool): Whether to claim rewards when unstaking
1048  
1049  **Returns:** `str` - Transaction hash
1050  
1051  #### `curve_claim_gauge_rewards(gauge_address)`
1052  
1053  Claim CRV and other rewards from a Curve gauge.
1054  
1055  **Parameters:**
1056  - `gauge_address` (str): Gauge contract address
1057  
1058  **Returns:** `str` - Transaction hash
1059  
1060  #### `get_curve_gauge_balance(gauge_address, account_address=None)`
1061  
1062  Get staked LP token balance in a Curve gauge.
1063  
1064  **Parameters:**
1065  - `gauge_address` (str): Gauge contract address
1066  - `account_address` (Optional[str]): Account address
1067  
1068  **Returns:** `Decimal` - Staked balance
1069  
1070  #### `get_curve_gauge_rewards(gauge_address, account_address=None)`
1071  
1072  Get claimable rewards from a Curve gauge.
1073  
1074  **Parameters:**
1075  - `gauge_address` (str): Gauge contract address
1076  - `account_address` (Optional[str]): Account address
1077  
1078  **Returns:** `Dict[str, Decimal]` - Dictionary mapping reward token addresses to amounts
1079  
1080  #### `get_curve_gauge_from_pool(pool_address)`
1081  
1082  Find the gauge address for a Curve pool.
1083  
1084  **Parameters:**
1085  - `pool_address` (str): Curve pool address
1086  
1087  **Returns:** `Optional[str]` - Gauge address if found
1088  
1089  ### Helper Methods
1090  
1091  #### `get_curve_pools_from_registry()`
1092  
1093  Get all pools from the Curve registry.
1094  
1095  **Returns:** `List[Dict[str, Any]]` - List of pool information
1096  
1097  #### `get_curve_pool_from_registry(pool_name)`
1098  
1099  Get a specific pool from the registry by name.
1100  
1101  **Parameters:**
1102  - `pool_name` (str): Pool name
1103  
1104  **Returns:** `Optional[Dict[str, Any]]` - Pool information if found
1105  
1106  #### `get_curve_gauge_balances_batch(gauge_addresses, account_address=None)`
1107  
1108  Query multiple gauge balances efficiently.
1109  
1110  **Parameters:**
1111  - `gauge_addresses` (List[str]): List of gauge addresses
1112  - `account_address` (Optional[str]): Account address
1113  
1114  **Returns:** `Dict[str, Decimal]` - Dictionary mapping gauge addresses to balances
1115  
1116  #### `get_curve_gauge_rewards_batch(gauge_addresses, account_address=None)`
1117  
1118  Query multiple gauge rewards efficiently.
1119  
1120  **Parameters:**
1121  - `gauge_addresses` (List[str]): List of gauge addresses
1122  - `account_address` (Optional[str]): Account address
1123  
1124  **Returns:** `Dict[str, Dict[str, Decimal]]` - Dictionary mapping gauge addresses to rewards
1125  
1126  #### `get_user_curve_positions_summary(account_address=None)`
1127  
1128  Get comprehensive overview of all user Curve positions.
1129  
1130  **Parameters:**
1131  - `account_address` (Optional[str]): Account address
1132  
1133  **Returns:** `Dict[str, Any]` - Summary with balances and rewards for all positions
1134  
1135  ---
1136  
1137  ## Utility Methods
1138  
1139  ### Token Operations
1140  
1141  #### `approve(token_address, spender_address, amount)`
1142  
1143  Approve a spender to spend tokens.
1144  
1145  **Parameters:**
1146  - `token_address` (str): Token contract address
1147  - `spender_address` (str): Spender address
1148  - `amount` (Union[int, float, Decimal, str]): Approval amount
1149  
1150  **Returns:** `str` - Transaction hash
1151  
1152  #### `transfer(token_address, recipient_address, amount)`
1153  
1154  Transfer tokens to another address.
1155  
1156  **Parameters:**
1157  - `token_address` (str): Token contract address
1158  - `recipient_address` (str): Recipient address
1159  - `amount` (Union[int, float, Decimal, str]): Transfer amount
1160  
1161  **Returns:** `str` - Transaction hash
1162  
1163  ### Transaction Building
1164  
1165  All write operations have corresponding `build_*_transaction()` methods that return unsigned transaction data instead of executing immediately. This allows for:
1166  - Offline signing
1167  - Gas estimation without execution
1168  - Batch transaction building
1169  
1170  **Example:**
1171  ```python
1172  # Build transaction without sending
1173  tx_data = client.build_mint_f_token_transaction(
1174      market_address="0x...",
1175      base_in=1.0
1176  )
1177  
1178  # Sign and broadcast separately
1179  signed_tx = client.account.sign_transaction(tx_data)
1180  tx_hash = client.w3.eth.send_raw_transaction(signed_tx.rawTransaction)
1181  ```
1182  
1183  ### Infrastructure Queries
1184  
1185  #### `get_pool_manager_info(pool_address)`
1186  
1187  Get Pool Manager information for a pool.
1188  
1189  **Parameters:**
1190  - `pool_address` (str): Pool address
1191  
1192  **Returns:** `Dict[str, Any]` - Pool information
1193  
1194  #### `get_reserve_pool_bonus_ratio(token_address)`
1195  
1196  Get bonus ratio for a token in the Reserve Pool.
1197  
1198  **Parameters:**
1199  - `token_address` (str): Token address
1200  
1201  **Returns:** `Decimal` - Bonus ratio
1202  
1203  #### `get_steth_treasury_info()`
1204  
1205  Get stETH Treasury information.
1206  
1207  **Returns:** `Dict[str, Any]` - Treasury information
1208  
1209  #### `get_treasury_nav()`
1210  
1211  Get Net Asset Values from the treasury.
1212  
1213  **Returns:** `Dict[str, Decimal]` with keys:
1214  - `base_nav`: Base token NAV
1215  - `f_nav`: F-token NAV
1216  - `x_nav`: X-token NAV
1217  
1218  #### `get_market_info(market_address)`
1219  
1220  Get information for a market.
1221  
1222  **Parameters:**
1223  - `market_address` (str): Market contract address
1224  
1225  **Returns:** `Dict[str, Any]` - Market information
1226  
1227  #### `get_peg_keeper_info()`
1228  
1229  Get Peg Keeper information.
1230  
1231  **Returns:** `Dict[str, Any]` - Peg Keeper information
1232  
1233  #### `get_position_info(position_id)`
1234  
1235  Get V2 position information.
1236  
1237  **Parameters:**
1238  - `position_id` (int): Position ID
1239  
1240  **Returns:** `Dict[str, Any]` - Position information
1241  
1242  ### Rebalance Pool Operations
1243  
1244  #### `deposit_to_rebalance_pool(pool_address, amount, recipient=None)`
1245  
1246  Deposit to a V1 rebalance pool.
1247  
1248  **Parameters:**
1249  - `pool_address` (str): Rebalance pool address
1250  - `amount` (Union[int, float, Decimal, str]): Deposit amount
1251  - `recipient` (Optional[str]): Recipient address
1252  
1253  **Returns:** `str` - Transaction hash
1254  
1255  #### `unlock_rebalance_pool_assets(pool_address, amount)`
1256  
1257  Unlock assets in a rebalance pool.
1258  
1259  **Parameters:**
1260  - `pool_address` (str): Rebalance pool address
1261  - `amount` (Union[int, float, Decimal, str]): Amount to unlock
1262  
1263  **Returns:** `str` - Transaction hash
1264  
1265  #### `withdraw_unlocked_rebalance_pool_assets(pool_address, claim_rewards=True)`
1266  
1267  Withdraw unlocked assets from a rebalance pool.
1268  
1269  **Parameters:**
1270  - `pool_address` (str): Rebalance pool address
1271  - `claim_rewards` (bool): Whether to claim rewards
1272  
1273  **Returns:** `str` - Transaction hash
1274  
1275  #### `claim_rebalance_pool_rewards(pool_address, tokens)`
1276  
1277  Claim rewards from a rebalance pool.
1278  
1279  **Parameters:**
1280  - `pool_address` (str): Rebalance pool address
1281  - `tokens` (List[str]): List of reward token addresses
1282  
1283  **Returns:** `str` - Transaction hash
1284  
1285  ### Gateway Operations
1286  
1287  #### `mint_f_token_via_gateway(amount_eth, min_f_token_out=0)`
1288  
1289  Mint f-token via the stETH Gateway using ETH.
1290  
1291  **Parameters:**
1292  - `amount_eth` (Union[int, float, Decimal, str]): Amount of ETH to deposit
1293  - `min_f_token_out` (Union[int, float, Decimal, str]): Minimum f-token output
1294  
1295  **Returns:** `str` - Transaction hash
1296  
1297  #### `mint_x_token_via_gateway(amount_eth, min_x_token_out=0)`
1298  
1299  Mint x-token via the stETH Gateway using ETH.
1300  
1301  **Parameters:**
1302  - `amount_eth` (Union[int, float, Decimal, str]): Amount of ETH to deposit
1303  - `min_x_token_out` (Union[int, float, Decimal, str]): Minimum x-token output
1304  
1305  **Returns:** `str` - Transaction hash
1306  
1307  ### Flash Loans
1308  
1309  #### `flash_loan(token_address, amount, receiver, data=b"")`
1310  
1311  Execute a flash loan.
1312  
1313  **Parameters:**
1314  - `token_address` (str): Token address
1315  - `amount` (Union[int, float, Decimal, str]): Loan amount
1316  - `receiver` (str): Receiver contract address
1317  - `data` (bytes): Additional data
1318  
1319  **Returns:** `str` - Transaction hash
1320  
1321  ### Swaps
1322  
1323  #### `swap(token_in, amount_in, encoding, routes)`
1324  
1325  Execute a swap via the Multi-Path Converter.
1326  
1327  **Parameters:**
1328  - `token_in` (str): Input token address
1329  - `amount_in` (Union[int, float, Decimal, str]): Input amount
1330  - `encoding` (int): Encoding type
1331  - `routes` (List[int]): Swap routes
1332  
1333  **Returns:** `str` - Transaction hash
1334  
1335  ---
1336  
1337  ## Error Handling
1338  
1339  The SDK uses a custom exception hierarchy for clear error reporting.
1340  
1341  ### Exception Classes
1342  
1343  #### `FXProtocolError`
1344  
1345  Base exception for all SDK errors.
1346  
1347  #### `TransactionFailedError(FXProtocolError)`
1348  
1349  Raised when a blockchain transaction fails.
1350  
1351  #### `InsufficientBalanceError(FXProtocolError)`
1352  
1353  Raised when the user has insufficient balance for an operation.
1354  
1355  #### `ContractCallError(FXProtocolError)`
1356  
1357  Raised when a read call to a contract fails.
1358  
1359  #### `InvalidAddressError(FXProtocolError)`
1360  
1361  Raised when an invalid Ethereum address is provided.
1362  
1363  #### `ConfigurationError(FXProtocolError)`
1364  
1365  Raised when the SDK is misconfigured (e.g., RPC connection failed).
1366  
1367  ### Error Handling Example
1368  
1369  ```python
1370  from fx_sdk.exceptions import (
1371      FXProtocolError,
1372      InsufficientBalanceError,
1373      ContractCallError
1374  )
1375  
1376  try:
1377      tx_hash = client.mint_f_token(
1378          market_address="0x...",
1379          base_in=1000.0
1380      )
1381  except InsufficientBalanceError as e:
1382      print(f"Insufficient balance: {e}")
1383  except ContractCallError as e:
1384      print(f"Contract call failed: {e}")
1385  except FXProtocolError as e:
1386      print(f"Protocol error: {e}")
1387  ```
1388  
1389  ---
1390  
1391  ## Examples
1392  
1393  ### Example 1: Check All Balances
1394  
1395  ```python
1396  from fx_sdk.client import ProtocolClient
1397  
1398  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
1399  
1400  # Get all protocol token balances
1401  balances = client.get_all_balances("0x1234...")
1402  
1403  for token, balance in balances.items():
1404      if balance > 0:
1405          print(f"{token}: {balance}")
1406  ```
1407  
1408  ### Example 2: Mint fxUSD
1409  
1410  ```python
1411  from fx_sdk.client import ProtocolClient
1412  
1413  # Initialize with private key from environment
1414  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
1415  
1416  # Mint fxUSD from stETH
1417  tx_hash = client.mint_f_token(
1418      market_address="0x...",
1419      base_in=1.0,  # 1 stETH
1420      min_f_token_out=0.99  # 1% slippage tolerance
1421  )
1422  
1423  print(f"Transaction: {tx_hash}")
1424  
1425  # Wait for confirmation
1426  receipt = client.w3.eth.wait_for_transaction_receipt(tx_hash)
1427  print(f"Confirmed in block: {receipt['blockNumber']}")
1428  ```
1429  
1430  ### Example 3: Convex Vault Management
1431  
1432  ```python
1433  from fx_sdk.client import ProtocolClient
1434  
1435  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
1436  
1437  # Get or create vault for pool 37 (fxUSD V2 Stability Pool)
1438  vault_address = client.get_convex_vault_address_or_create(pool_id=37)
1439  
1440  # Deposit LP tokens
1441  tx_hash = client.deposit_to_convex_vault(
1442      vault_address=vault_address,
1443      amount=100.0
1444  )
1445  
1446  # Check balance
1447  balance = client.get_convex_vault_balance(vault_address)
1448  print(f"Staked: {balance}")
1449  
1450  # Check rewards
1451  rewards = client.get_convex_vault_rewards(vault_address)
1452  for token, amount in rewards['amounts'].items():
1453      print(f"Reward {token}: {amount}")
1454  
1455  # Claim rewards
1456  if sum(rewards['amounts'].values()) > 0:
1457      tx_hash = client.claim_convex_vault_rewards(vault_address)
1458      print(f"Claimed rewards: {tx_hash}")
1459  ```
1460  
1461  ### Example 4: Curve Swap
1462  
1463  ```python
1464  from fx_sdk.client import ProtocolClient
1465  
1466  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
1467  
1468  # Find pool
1469  pool_address = client.find_curve_pool(
1470      token_a="0x085780639CC2cACd35E474e71f4d000e2405d8f6",  # fxUSD
1471      token_b="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"  # USDC
1472  )
1473  
1474  # Calculate swap rate
1475  amount_out = client.get_curve_swap_rate(
1476      pool_address=pool_address,
1477      token_in="0x085780639CC2cACd35E474e71f4d000e2405d8f6",
1478      token_out="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
1479      amount_in=1000.0
1480  )
1481  
1482  print(f"Expected output: {amount_out} USDC")
1483  
1484  # Execute swap
1485  tx_hash = client.curve_swap(
1486      pool_address=pool_address,
1487      token_in="0x085780639CC2cACd35E474e71f4d000e2405d8f6",
1488      token_out="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
1489      amount_in=1000.0,
1490      min_amount_out=amount_out * Decimal("0.995")  # 0.5% slippage
1491  )
1492  
1493  print(f"Swap transaction: {tx_hash}")
1494  ```
1495  
1496  ### Example 5: Governance Operations
1497  
1498  ```python
1499  from fx_sdk.client import ProtocolClient
1500  import time
1501  
1502  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
1503  
1504  # Lock FXN for 1 year
1505  unlock_time = int(time.time()) + (365 * 24 * 60 * 60)
1506  tx_hash = client.deposit_to_vefxn(
1507      amount=1000.0,
1508      unlock_time=unlock_time
1509  )
1510  
1511  # Vote for gauge weight
1512  tx_hash = client.vote_for_gauge_weight(
1513      gauge_address="0x...",
1514      user_weight=5000  # 50%
1515  )
1516  
1517  # Claim all gauge rewards
1518  tx_hashes = client.claim_all_gauge_rewards()
1519  print(f"Claimed from {len(tx_hashes)} gauges")
1520  ```
1521  
1522  ### Example 6: Read-Only Analytics
1523  
1524  ```python
1525  from fx_sdk.client import ProtocolClient
1526  
1527  # No private key needed for read operations
1528  client = ProtocolClient(rpc_url="https://eth.llamarpc.com")
1529  
1530  # Get protocol metrics
1531  nav = client.get_treasury_nav()
1532  print(f"Base NAV: {nav['base_nav']}")
1533  print(f"F-token NAV: {nav['f_nav']}")
1534  print(f"X-token NAV: {nav['x_nav']}")
1535  
1536  # Get stETH price
1537  price = client.get_steth_price()
1538  print(f"stETH Price: {price}")
1539  
1540  # Get fxUSD supply
1541  supply = client.get_fxusd_total_supply()
1542  print(f"fxUSD Total Supply: {supply}")
1543  
1544  # Get pool information
1545  pool_info = client.get_pool_manager_info("0x...")
1546  print(f"Pool Info: {pool_info}")
1547  ```
1548  
1549  ---
1550  
1551  ## Complete Method Reference
1552  
1553  For a complete list of all 155+ public methods, see the source code or use Python's `help()` function:
1554  
1555  ```python
1556  from fx_sdk.client import ProtocolClient
1557  
1558  # Get help for a specific method
1559  help(ProtocolClient.mint_f_token)
1560  
1561  # List all methods
1562  methods = [m for m in dir(ProtocolClient) if not m.startswith('_')]
1563  print(f"Total methods: {len(methods)}")
1564  ```
1565  
1566  ---
1567  
1568  ## Additional Resources
1569  
1570  - **f(x) Protocol Website**: https://fx.aladdin.club/
1571  - **PyPI Package**: https://pypi.org/project/fx-sdk/
1572  - **GitHub Repository**: (if public)
1573  - **Documentation**: This file
1574  
1575  ---
1576  
1577  ## Version History
1578  
1579  ### v0.3.0 (December 22, 2025)
1580  - Removed APY calculation methods
1581  - Enhanced error handling
1582  - Improved documentation
1583  
1584  ### v0.2.0 (December 22, 2025)
1585  - Added Convex Finance integration
1586  - Added Curve Finance integration
1587  - Added batch operations
1588  - Added helper methods
1589  
1590  ### v0.1.0 (December 20, 2025)
1591  - Initial release
1592  - Core f(x) Protocol V1 and V2 support
1593  - Secure authentication
1594  - High-precision Decimal handling
1595  
1596  ---
1597  
1598  **End of Documentation**
1599