gmx.lagoon

Documentation for eth_defi.gmx.lagoon Python module.

GMX trading integration for Lagoon vaults.

This module provides a LagoonGMXTradingWallet class that implements the BaseWallet interface, enabling the standard GMX CCXT adapter to trade through a Lagoon vault without any modifications.

Example usage:

from eth_defi.gmx.ccxt import GMX
from eth_defi.gmx.lagoon import LagoonGMXTradingWallet
from eth_defi.erc_4626.vault_protocol.lagoon import LagoonVault
from eth_defi.hotwallet import HotWallet

# Set up vault and asset manager
vault = LagoonVault(web3, vault_address)
asset_manager = HotWallet.from_private_key("0x...")

# Create vault wallet
wallet = LagoonGMXTradingWallet(vault, asset_manager)

# Use standard GMX adapter with vault wallet
gmx = GMX(params={"rpcUrl": rpc_url}, wallet=wallet)
gmx.load_markets()

# Trade through vault - standard GMX API
order = gmx.create_order(
    symbol="ETH/USD",
    type="market",
    side="buy",
    amount=0,
    params={"size_usd": 1000, "leverage": 2.0},
)
class LagoonGMXTradingWallet

Bases: eth_defi.basewallet.BaseWallet

Wallet implementation that routes transactions through a Lagoon vault.

This wallet wraps all transactions through the vault’s TradingStrategyModuleV0.performCall() method, enabling vault-based trading with protocols like GMX.

The wallet implements the full BaseWallet interface, making it a drop-in replacement for HotWallet when used with the GMX CCXT adapter.

Architecture:

GMX CCXT Adapter
└── wallet: LagoonGMXTradingWallet
    ├── vault: LagoonVault (holds assets in Safe multisig)
    ├── asset_manager: HotWallet (signs wrapped transactions)
    └── sign_transaction_with_new_nonce():
        1. Wrap tx in performCall(to, data, value)
        2. Sign with asset_manager
        3. Return SignedTransactionWithNonce

The Safe address is used as the trading account, meaning: - Positions are owned by the Safe, not the asset manager - Collateral tokens must be in the Safe - Token approvals are done from the Safe via performCall()

Example:

vault = LagoonVault(web3, vault_address)
asset_manager = HotWallet.from_private_key("0x...")

wallet = LagoonGMXTradingWallet(vault, asset_manager)

# Use with GMX
gmx = GMX(params={"rpcUrl": rpc_url}, wallet=wallet)
order = gmx.create_order("ETH/USD", "market", "buy", 0, params={"size_usd": 1000})

Initialise the Lagoon wallet.

Parameters
  • vault – Lagoon vault with TradingStrategyModuleV0 configured. The vault’s Safe address will be used as the trading account.

  • asset_manager – Hot wallet of the asset manager who will sign transactions. Must have the asset manager role on the vault.

  • gas_buffer – Additional gas to add for performCall overhead. Default is 200,000 gas.

  • forward_eth

    Whether the asset manager’s hot wallet forwards ETH for execution fees (e.g. GMX keeper fees).

    • False (default): Safe pays execution fees from its own ETH balance. The Safe must be pre-funded with ETH.

    • True: The asset manager sends ETH with the performCall transaction, and the module forwards it to the Safe. Requires TradingStrategyModuleV0 v0.4+.

__init__(vault, asset_manager, gas_buffer=200000, forward_eth=False)

Initialise the Lagoon wallet.

Parameters
  • vault – Lagoon vault with TradingStrategyModuleV0 configured. The vault’s Safe address will be used as the trading account.

  • asset_manager (eth_defi.hotwallet.HotWallet) – Hot wallet of the asset manager who will sign transactions. Must have the asset manager role on the vault.

  • gas_buffer (int) – Additional gas to add for performCall overhead. Default is 200,000 gas.

  • forward_eth (bool) –

    Whether the asset manager’s hot wallet forwards ETH for execution fees (e.g. GMX keeper fees).

    • False (default): Safe pays execution fees from its own ETH balance. The Safe must be pre-funded with ETH.

    • True: The asset manager sends ETH with the performCall transaction, and the module forwards it to the Safe. Requires TradingStrategyModuleV0 v0.4+.

property address: eth_typing.evm.HexAddress

Get the wallet’s Ethereum address.

Returns the vault’s Safe address, as this is the account that owns positions and holds collateral.

property gas_address: eth_typing.evm.HexAddress

Get the address that pays gas for transactions.

In lagoon mode, the asset manager pays gas, not the Safe.

get_main_address()

Get the main Ethereum address for this wallet.

Returns the vault’s Safe address.

Return type

eth_typing.evm.HexAddress

sync_nonce(web3)

Synchronise the nonce with the blockchain.

Delegates to the asset manager’s nonce, as the asset manager is the one signing and broadcasting transactions.

Parameters

web3 (web3.main.Web3) –

Return type

None

allocate_nonce()

Get the next available nonce.

Delegates to the asset manager.

Return type

int

sign_transaction_with_new_nonce(tx)

Sign a transaction with a new nonce.

This is the key method that wraps the transaction through the vault’s performCall() before signing.

Parameters

tx (dict) – Transaction dict with ‘to’, ‘data’, and optionally ‘value’ and ‘gas’.

Returns

Signed transaction ready for broadcasting.

Return type

eth_defi.hotwallet.SignedTransactionWithNonce

sign_bound_call_with_new_nonce(func, tx_params=None, web3=None, fill_gas_price=False, value=None)

Sign a contract function call with a new nonce.

Wraps the function call through performCall before signing.

Parameters
  • func (web3.contract.contract.ContractFunction) – Contract function to call.

  • tx_params (Optional[dict]) – Additional transaction parameters.

  • web3 (Optional[web3.main.Web3]) – Web3 instance (uses self.web3 if not provided).

  • fill_gas_price (bool) – Whether to fill in gas price from network.

  • value (Optional[int]) – ETH value to send with transaction.

Returns

Signed transaction ready for broadcasting.

Return type

eth_defi.hotwallet.SignedTransactionWithNonce

get_native_currency_balance(web3)

Get the wallet’s native currency balance.

Returns the Safe’s ETH balance, as this is where trading funds are held.

Parameters

web3 (web3.main.Web3) –

Return type

decimal.Decimal

static fill_in_gas_price(web3, tx)

Fill in gas price details for a transaction.

Delegates to HotWallet’s implementation.

Parameters
  • web3 (web3.main.Web3) –

  • tx (dict) –

Return type

dict

approve_gmx_collateral_via_vault(vault, asset_manager, collateral_token, amount, broadcast_callback=None)

Approve GMX SyntheticsRouter to spend collateral from the vault’s Safe.

This wraps a token approval through the vault’s TradingStrategyModuleV0, allowing the Safe to approve the GMX SyntheticsRouter to spend tokens.

Parameters
Returns

Transaction hash

Return type

hexbytes.main.HexBytes

Example:

from eth_defi.gmx.lagoon.approvals import approve_gmx_collateral_via_vault, UNLIMITED

tx_hash = approve_gmx_collateral_via_vault(
    vault=vault,
    asset_manager=asset_manager,
    collateral_token=usdc,
    amount=UNLIMITED,
)
approve_gmx_execution_fee_via_vault(vault, asset_manager, weth_token, amount, broadcast_callback=None)

Approve GMX ExchangeRouter to spend WETH from the vault’s Safe.

Note

GMX execution fees are normally paid as native ETH via the sendWnt() payable function, which does not require any ERC-20 approval. When using LagoonGMXTradingWallet with forward_eth=True, native ETH is forwarded through performCall and this WETH approval is not used.

This approval is only relevant if the Safe holds WETH and the ExchangeRouter needs to pull it via transferFrom (e.g. a non-standard fee payment path). In most setups this function can be skipped.

Parameters
Returns

Transaction hash

Return type

hexbytes.main.HexBytes

Modules

eth_defi.gmx.lagoon.approvals

Token approval functions for GMX trading through Lagoon vaults.

eth_defi.gmx.lagoon.wallet

Lagoon vault wallet for GMX trading.