Lido¶
Connector for Lido liquid staking protocol.
almanak.framework.connectors.lido
¶
Lido Connector.
This module provides an adapter for interacting with Lido liquid staking protocol.
Lido is a decentralized liquid staking protocol supporting: - Stake ETH to receive stETH - Wrap stETH to wstETH (non-rebasing) - Unwrap wstETH to stETH
Supported chains: - Ethereum (full staking + wrap/unwrap) - Arbitrum, Optimism, Polygon (wstETH only)
Example
from almanak.framework.connectors.lido import LidoAdapter, LidoConfig
config = LidoConfig( chain="ethereum", wallet_address="0x...", ) adapter = LidoAdapter(config)
Stake ETH to receive stETH¶
result = adapter.stake(amount=Decimal("1.0"))
Wrap stETH to wstETH¶
result = adapter.wrap(amount=Decimal("1.0"))
LidoAdapter
¶
Adapter for Lido liquid staking protocol.
This adapter provides methods for interacting with Lido: - Stake ETH to receive stETH - Wrap stETH to wstETH (non-rebasing) - Unwrap wstETH back to stETH
Note: stETH is a rebasing token - balances change daily as rewards accrue. wstETH is non-rebasing and preferred for DeFi integrations.
Example
config = LidoConfig( chain="ethereum", wallet_address="0x...", ) adapter = LidoAdapter(config)
Stake ETH to get stETH¶
result = adapter.stake(Decimal("1.0"))
Wrap stETH to wstETH¶
result = adapter.wrap(Decimal("1.0"))
Unwrap wstETH back to stETH¶
result = adapter.unwrap(Decimal("1.0"))
Initialize the adapter.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
LidoConfig
|
Adapter configuration |
required |
token_resolver
|
TokenResolver | None
|
Optional TokenResolver instance. If None, uses singleton. |
None
|
stake
¶
stake(
amount: Decimal,
referral: str = "0x0000000000000000000000000000000000000000",
) -> TransactionResult
Build a stake transaction to receive stETH.
Stakes ETH to the Lido stETH contract and receives stETH in return. Only available on Ethereum mainnet.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
Decimal
|
Amount of ETH to stake |
required |
referral
|
str
|
Referral address (default: zero address) |
'0x0000000000000000000000000000000000000000'
|
Returns:
| Type | Description |
|---|---|
TransactionResult
|
TransactionResult with transaction data |
wrap
¶
Build a wrap transaction to convert stETH to wstETH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
Decimal
|
Amount of stETH to wrap |
required |
Returns:
| Type | Description |
|---|---|
TransactionResult
|
TransactionResult with transaction data |
unwrap
¶
Build an unwrap transaction to convert wstETH to stETH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amount
|
Decimal
|
Amount of wstETH to unwrap |
required |
Returns:
| Type | Description |
|---|---|
TransactionResult
|
TransactionResult with transaction data |
request_withdrawal
¶
Build a withdrawal request transaction.
Requests stETH withdrawal from the Lido withdrawal queue. Each amount in the list creates a separate withdrawal request. Only available on Ethereum mainnet.
Note: Requires prior approval of stETH to the withdrawal queue contract.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
amounts
|
list[Decimal]
|
List of stETH amounts to withdraw |
required |
owner
|
str | None
|
Address to own the withdrawal requests (default: wallet_address) |
None
|
Returns:
| Type | Description |
|---|---|
TransactionResult
|
TransactionResult with transaction data |
claim_withdrawals
¶
Build a claim withdrawals transaction.
Claims finalized withdrawal requests, sending ETH to msg.sender. Only available on Ethereum mainnet.
Note: Request IDs are returned when calling requestWithdrawals(). Hints can be obtained from findCheckpointHints() on the withdrawal queue, or pass None/empty list for the contract to compute them (higher gas).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
request_ids
|
list[int]
|
List of withdrawal request IDs to claim |
required |
hints
|
list[int] | None
|
Checkpoint hints for each request ID (optional, improves gas) |
None
|
Returns:
| Type | Description |
|---|---|
TransactionResult
|
TransactionResult with transaction data |
compile_stake_intent
¶
Compile a StakeIntent to an ActionBundle.
This method converts a high-level StakeIntent into executable transaction data. It handles the receive_wrapped flag: - If receive_wrapped=True: stake ETH -> stETH, then wrap stETH -> wstETH - If receive_wrapped=False: stake ETH -> stETH only
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
intent
|
StakeIntent
|
The StakeIntent to compile |
required |
market_snapshot
|
Any | None
|
Optional market data (not used for Lido) |
None
|
Returns:
| Type | Description |
|---|---|
ActionBundle
|
ActionBundle containing transaction(s) for execution |
Raises:
| Type | Description |
|---|---|
ValueError
|
If amount="all" is not resolved before compilation |
compile_unstake_intent
¶
compile_unstake_intent(
intent: UnstakeIntent,
market_snapshot: Any | None = None,
) -> ActionBundle
Compile an UnstakeIntent to an ActionBundle.
This method converts a high-level UnstakeIntent into executable transaction data. It handles the token_in type: - If token_in is wstETH: unwrap wstETH -> stETH first, then request withdrawal - If token_in is stETH: request withdrawal directly
Note: This only initiates the withdrawal request. Actual ETH claiming happens separately after the withdrawal is finalized (claim_withdrawals).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
intent
|
UnstakeIntent
|
The UnstakeIntent to compile |
required |
market_snapshot
|
Any | None
|
Optional market data (not used for Lido) |
None
|
Returns:
| Type | Description |
|---|---|
ActionBundle
|
ActionBundle containing transaction(s) for execution |
Raises:
| Type | Description |
|---|---|
ValueError
|
If amount="all" is not resolved before compilation |
LidoConfig
dataclass
¶
Configuration for Lido adapter.
Attributes:
| Name | Type | Description |
|---|---|---|
chain |
str
|
Blockchain network (ethereum, arbitrum, optimism, polygon) |
wallet_address |
str
|
User wallet address |
TransactionResult
dataclass
¶
TransactionResult(
success: bool,
tx_data: dict[str, Any] | None = None,
gas_estimate: int = 0,
description: str = "",
error: str | None = None,
)
Result of a transaction build operation.
Attributes:
| Name | Type | Description |
|---|---|---|
success |
bool
|
Whether operation succeeded |
tx_data |
dict[str, Any] | None
|
Transaction data (to, value, data) |
gas_estimate |
int
|
Estimated gas |
description |
str
|
Human-readable description |
error |
str | None
|
Error message if failed |
LidoEventType
¶
Bases: Enum
Lido event types.
LidoReceiptParser
¶
Parser for Lido transaction receipts.
Refactored to use base infrastructure utilities for hex decoding and event registry management. Handles multiple contracts (stETH, wstETH, withdrawal queue) with different event types.
Initialize the parser.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chain
|
str
|
Blockchain network (ethereum, arbitrum, optimism, polygon) |
'ethereum'
|
**kwargs
|
Any
|
Additional arguments (ignored for compatibility) |
{}
|
parse_receipt
¶
Parse a transaction receipt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
receipt
|
dict[str, Any]
|
Transaction receipt dict |
required |
Returns:
| Type | Description |
|---|---|
ParseResult
|
ParseResult with extracted events |
parse_stake
¶
Parse a Submitted (stake) event from a single log entry.
parse_wrap
¶
Parse a wrap event (Transfer from zero address) from a single log entry.
parse_unwrap
¶
Parse an unwrap event (Transfer to zero address) from a single log entry.
parse_withdrawal_requested
¶
Parse a WithdrawalRequested event from a single log entry.
parse_withdrawals_claimed
¶
Parse a WithdrawalClaimed event from a single log entry.
is_lido_event
¶
Check if a topic is a known Lido event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
topic
|
str | bytes
|
Event topic (supports bytes, hex string with/without 0x, any case) |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if topic is a known Lido event |
get_event_type
¶
Get the event type for a topic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
topic
|
str | bytes
|
Event topic (supports bytes, hex string with/without 0x, any case) |
required |
log
|
dict[str, Any] | None
|
Optional log dict for disambiguating Transfer events |
None
|
Returns:
| Type | Description |
|---|---|
LidoEventType
|
Event type or UNKNOWN |
extract_stake_amount
¶
Extract stake amount from transaction receipt.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
receipt
|
dict[str, Any]
|
Transaction receipt dict with 'logs' field |
required |
Returns:
| Type | Description |
|---|---|
int | None
|
Stake amount in wei if found, None otherwise |
extract_shares_received
¶
Extract stETH/wstETH shares received from transaction receipt.
When staking ETH, user receives stETH. When wrapping stETH, user receives wstETH.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
receipt
|
dict[str, Any]
|
Transaction receipt dict with 'logs' field |
required |
Returns:
| Type | Description |
|---|---|
int | None
|
Shares received in wei if found, None otherwise |
extract_unstake_amount
¶
Extract unstake amount from transaction receipt.
This is the amount of stETH requested for withdrawal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
receipt
|
dict[str, Any]
|
Transaction receipt dict with 'logs' field |
required |
Returns:
| Type | Description |
|---|---|
int | None
|
Unstake amount in wei if found, None otherwise |
extract_underlying_received
¶
Extract underlying ETH received from withdrawal claim.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
receipt
|
dict[str, Any]
|
Transaction receipt dict with 'logs' field |
required |
Returns:
| Type | Description |
|---|---|
int | None
|
ETH received in wei if found, None otherwise |
ParseResult
dataclass
¶
ParseResult(
success: bool,
stakes: list[StakeEventData] = list(),
wraps: list[WrapEventData] = list(),
unwraps: list[UnwrapEventData] = list(),
withdrawal_requests: list[
WithdrawalRequestedEventData
] = list(),
withdrawal_claims: list[
WithdrawalClaimedEventData
] = list(),
error: str | None = None,
transaction_hash: str = "",
block_number: int = 0,
)
Result of parsing a receipt.
StakeEventData
dataclass
¶
Parsed data from Submitted event (stake operation).
UnwrapEventData
dataclass
¶
Parsed data from unwrap operation (Transfer event on wstETH).
WithdrawalClaimedEventData
dataclass
¶
Parsed data from WithdrawalClaimed event.
WithdrawalRequestedEventData
dataclass
¶
WithdrawalRequestedEventData(
request_id: int,
requestor: str,
owner: str,
amount_of_steth: Decimal,
amount_of_shares: Decimal,
)
Parsed data from WithdrawalRequested event.