Skip to content

JoeLend

Connector for the Joe Lend (Banker Joe) lending protocol on Avalanche (dormant — protocol wound down).

almanak.connectors.joelend

Joe Lend (Banker Joe) Lending Connector — DORMANT / DEPRECATED.

Joe Lend (the lending arm of Trader Joe / LFJ on Avalanche) was wound down by its governance in 2026. The on-chain jToken contracts now revert every supply/borrow/repay/withdraw call with Error: wind down.

The connector has been removed from the SDK's officially supported protocol surface (info matrix, vocabulary, execution config, CLI, demo strategies). JoeLendAdapter is retained only so historical receipts can still be parsed via JoeLendReceiptParser; instantiating the adapter raises JoeLendDeprecatedError on construction.

Full removal is tracked for July (VIB-3960).

JoeLendAdapter

JoeLendAdapter(
    config: JoeLendConfig,
    token_resolver: TokenResolver | None = None,
)

Adapter for Joe Lend (Banker Joe) lending protocol on Avalanche.

Provides methods to build transactions for supply, withdraw, borrow, and repay operations using the jToken (Compound V2) architecture.

get_market_info

get_market_info(asset: str) -> JoeLendMarketInfo | None

Get market info for an asset.

get_j_token_address

get_j_token_address(asset: str) -> str | None

Get the jToken address for an asset.

get_supported_assets

get_supported_assets() -> list[str]

Get list of supported asset symbols.

supply

supply(asset: str, amount: Decimal) -> TransactionResult

Build a supply (lend) transaction.

For ERC20 tokens: calls mint(uint256) on the jToken. For AVAX: calls mint() payable on jAVAX.

Parameters:

Name Type Description Default
asset str

Asset symbol (e.g., "USDC", "AVAX")

required
amount Decimal

Amount in underlying token units (e.g., 1000 USDC)

required

Returns:

Type Description
TransactionResult

TransactionResult with TX data for execution

withdraw

withdraw(
    asset: str,
    amount: Decimal,
    *,
    withdraw_all: bool = False,
    redeem_amount: int | None = None,
) -> TransactionResult

Build a withdraw transaction.

Calls redeemUnderlying(uint256) on the jToken to withdraw exact underlying amount. For withdraw_all with redeem_amount, uses redeem(uint256) with exact jToken count. For withdraw_all with amount > 0, uses redeemUnderlying(amount_wei) with the tracked amount.

Parameters:

Name Type Description Default
asset str

Asset symbol

required
amount Decimal

Amount of underlying to withdraw

required
withdraw_all bool

If True, withdraw entire balance

False
redeem_amount int | None

Exact jToken amount for redeem() when withdraw_all=True. Not yet wired from the compiler — reserved for future use when the compiler can query on-chain jToken balances.

None

Returns:

Type Description
TransactionResult

TransactionResult with TX data

borrow

borrow(asset: str, amount: Decimal) -> TransactionResult

Build a borrow transaction.

Calls borrow(uint256) on the jToken. Requires collateral to be supplied and enterMarkets() called first.

Parameters:

Name Type Description Default
asset str

Asset symbol to borrow

required
amount Decimal

Amount to borrow in underlying units

required

Returns:

Type Description
TransactionResult

TransactionResult with TX data

repay

repay(
    asset: str, amount: Decimal, *, repay_all: bool = False
) -> TransactionResult

Build a repay transaction.

For ERC20: calls repayBorrow(uint256) on the jToken. For AVAX: calls repayBorrow() payable on jAVAX. For repay_all on ERC20: uses MAX_UINT256 to repay full debt. For repay_all on native AVAX: caller must pass exact debt as amount (MAX_UINT256 trick doesn't apply to msg.value).

Parameters:

Name Type Description Default
asset str

Asset symbol

required
amount Decimal

Amount to repay

required
repay_all bool

If True, repay entire outstanding debt

False

Returns:

Type Description
TransactionResult

TransactionResult with TX data

enter_markets

enter_markets(assets: list[str]) -> TransactionResult

Build an enterMarkets transaction to enable assets as collateral.

Parameters:

Name Type Description Default
assets list[str]

List of asset symbols to enable as collateral

required

Returns:

Type Description
TransactionResult

TransactionResult with TX data

exit_market

exit_market(asset: str) -> TransactionResult

Build an exitMarket transaction to remove an asset from collateral.

Note: exitMarket is per-asset (not array), unlike enterMarkets. Will revert if the user has outstanding borrows against this collateral.

Parameters:

Name Type Description Default
asset str

Asset symbol to remove from collateral

required

Returns:

Type Description
TransactionResult

TransactionResult with TX data

JoeLendConfig dataclass

JoeLendConfig(
    chain: str = "avalanche",
    wallet_address: str = "",
    default_slippage_bps: int = 50,
)

Configuration for Joe Lend adapter.

JoeLendDeprecatedError

Bases: RuntimeError

Raised on any attempt to use the Joe Lend connector.

The protocol was wound down by governance; on-chain calls revert with Error: wind down. We fail fast here rather than letting strategies discover the wind-down only after a real submission attempt.

JoeLendMarketInfo dataclass

JoeLendMarketInfo(
    asset: str,
    j_token_address: str,
    underlying_address: str | None,
    decimals: int,
    is_native: bool,
)

Information about a Joe Lend market (jToken).

JoeLendPosition dataclass

JoeLendPosition(
    supplied: dict[str, Decimal] = dict(),
    borrowed: dict[str, Decimal] = dict(),
)

User position in Joe Lend.

TransactionResult dataclass

TransactionResult(
    success: bool,
    tx_data: dict[str, Any] | None = None,
    gas_estimate: int = 0,
    description: str = "",
    error: str | None = None,
)

Result of building a transaction.

JoeLendEvent dataclass

JoeLendEvent(
    event_type: JoeLendEventType,
    event_name: str,
    log_index: int,
    transaction_hash: str,
    block_number: int,
    contract_address: str,
    data: dict[str, Any],
    raw_topics: list[str] = list(),
    raw_data: str = "",
    timestamp: datetime = (lambda: datetime.now(UTC))(),
)

Parsed Joe Lend event.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

from_dict classmethod

from_dict(data: dict[str, Any]) -> JoeLendEvent

Create from dictionary.

JoeLendEventType

Bases: Enum

Joe Lend event types.

JoeLendReceiptParser

JoeLendReceiptParser(
    underlying_decimals: int = 18, **kwargs: Any
)

Parse Joe Lend transaction receipts.

Extracts supply, withdraw, borrow, and repay amounts from Compound V2-style events (Mint, Redeem, Borrow, RepayBorrow).

parse_receipt

parse_receipt(
    receipt: dict[str, Any],
    j_token_address: str | None = None,
) -> ParseResult

Parse a transaction receipt for Joe Lend events.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Transaction receipt dict with 'logs' field

required
j_token_address str | None

Optional filter for specific jToken

None

Returns:

Type Description
ParseResult

ParseResult with extracted events and amounts

parse_logs

parse_logs(
    logs: list[dict[str, Any]],
    tx_hash: str = "",
    block_number: int = 0,
) -> list[JoeLendEvent]

Parse a list of log entries into Joe Lend events.

extract_supply_amount

extract_supply_amount(
    receipt: dict[str, Any],
) -> int | None

Extract the raw SUPPLY (Mint mintAmount) amount in token wei, or None.

Called by ResultEnricher for SUPPLY intents (field: supply_amount).

extract_borrow_amount

extract_borrow_amount(
    receipt: dict[str, Any],
) -> int | None

Extract the raw BORROW (Borrow borrowAmount) amount in token wei, or None.

Called by ResultEnricher for BORROW intents (field: borrow_amount).

extract_withdraw_amount

extract_withdraw_amount(
    receipt: dict[str, Any],
) -> int | None

Extract the raw WITHDRAW (Redeem redeemAmount) amount in token wei, or None.

Called by ResultEnricher for WITHDRAW intents (field: withdraw_amount).

extract_repay_amount

extract_repay_amount(receipt: dict[str, Any]) -> int | None

Extract the raw REPAY (RepayBorrow repayAmount) amount in token wei, or None.

Called by ResultEnricher for REPAY intents (field: repay_amount).

extract_supply_data

extract_supply_data(result: dict[str, Any]) -> dict | None

Extract supply data from receipt (legacy API).

extract_borrow_data

extract_borrow_data(result: dict[str, Any]) -> dict | None

Extract borrow data from receipt (legacy API).

extract_withdraw_data

extract_withdraw_data(
    result: dict[str, Any],
) -> dict | None

Extract withdraw data from receipt (legacy API).

extract_repay_data

extract_repay_data(result: dict[str, Any]) -> dict | None

Extract repay data from receipt (legacy API).

ParseResult dataclass

ParseResult(
    success: bool,
    events: list[JoeLendEvent] = list(),
    supply_amount: Decimal = Decimal("0"),
    withdraw_amount: Decimal = Decimal("0"),
    borrow_amount: Decimal = Decimal("0"),
    repay_amount: Decimal = Decimal("0"),
    j_tokens_minted: Decimal = Decimal("0"),
    j_tokens_redeemed: Decimal = Decimal("0"),
    error: str | None = None,
)

Result of parsing a transaction receipt.

to_dict

to_dict() -> dict[str, Any]

Convert to dictionary.

__getattr__

__getattr__(name: str) -> Any

PEP 562 lazy attribute access.