Saltar a contenido

Kamino

Connector for Kamino lending protocol on Solana.

almanak.framework.connectors.kamino

Kamino Finance Lending Protocol Connector.

Kamino is the primary lending protocol on Solana (~$2.8B TVL), providing Aave-style lending/borrowing with a REST API.

This connector provides: - KaminoClient: HTTP client for the Kamino Finance API - KaminoAdapter: Adapter for converting lending intents to Solana transactions - KaminoReceiptParser: Balance-delta parser for extracting lending results

Example

from almanak.framework.connectors.kamino import KaminoClient, KaminoConfig

config = KaminoConfig(wallet_address="your-solana-pubkey") client = KaminoClient(config)

Get reserves for the main market

reserves = client.get_reserves()

Build a deposit transaction

tx = client.deposit(reserve=reserves[0].address, amount="100.0")

KaminoAdapter

KaminoAdapter(
    config: KaminoConfig,
    token_resolver: TokenResolver | None = None,
)

Adapter for Kamino Finance integration with the Intent system.

Converts lending intents (Supply, Borrow, Repay, Withdraw) into ActionBundles containing serialized Solana VersionedTransactions from Kamino's REST API.

Example

config = KaminoConfig(wallet_address="your-solana-pubkey") adapter = KaminoAdapter(config)

intent = SupplyIntent(protocol="kamino", token="USDC", amount=Decimal("100")) bundle = adapter.compile_supply_intent(intent)

Initialize the Kamino adapter.

Parameters:

Name Type Description Default
config KaminoConfig

Kamino client configuration

required
token_resolver TokenResolver | None

Optional TokenResolver instance

None

compile_supply_intent

compile_supply_intent(intent: SupplyIntent) -> ActionBundle

Compile a SupplyIntent to an ActionBundle using Kamino.

Parameters:

Name Type Description Default
intent SupplyIntent

The SupplyIntent to compile

required

Returns:

Type Description
ActionBundle

ActionBundle containing a serialized Solana transaction

compile_borrow_intent

compile_borrow_intent(intent: BorrowIntent) -> ActionBundle

Compile a BorrowIntent to an ActionBundle using Kamino.

Note: Kamino's borrow endpoint only handles the borrow action. If collateral needs to be deposited first, the compiler should emit a SupplyIntent + BorrowIntent sequence.

Parameters:

Name Type Description Default
intent BorrowIntent

The BorrowIntent to compile

required

Returns:

Type Description
ActionBundle

ActionBundle containing a serialized Solana transaction

compile_repay_intent

compile_repay_intent(intent: RepayIntent) -> ActionBundle

Compile a RepayIntent to an ActionBundle using Kamino.

Parameters:

Name Type Description Default
intent RepayIntent

The RepayIntent to compile

required

Returns:

Type Description
ActionBundle

ActionBundle containing a serialized Solana transaction

compile_withdraw_intent

compile_withdraw_intent(
    intent: WithdrawIntent,
) -> ActionBundle

Compile a WithdrawIntent to an ActionBundle using Kamino.

Parameters:

Name Type Description Default
intent WithdrawIntent

The WithdrawIntent to compile

required

Returns:

Type Description
ActionBundle

ActionBundle containing a serialized Solana transaction

KaminoClient

KaminoClient(config: KaminoConfig)

Client for interacting with the Kamino Finance REST API.

This client provides methods for: - Listing lending markets and reserves - Building deposit, borrow, repay, and withdraw transactions

All transaction endpoints return base64-encoded unsigned VersionedTransactions. No authentication is required.

Example

config = KaminoConfig(wallet_address="your-solana-wallet-pubkey") client = KaminoClient(config)

reserves = client.get_reserves() tx = client.deposit(reserve=reserves[0].address, amount="100.0")

Initialize the Kamino client.

Parameters:

Name Type Description Default
config KaminoConfig

Kamino client configuration

required

wallet_address property

wallet_address: str

Get the configured wallet address.

get_markets

get_markets() -> list[KaminoMarket]

List all available lending markets.

Returns:

Type Description
list[KaminoMarket]

List of KaminoMarket objects

Raises:

Type Description
KaminoAPIError

If the API request fails

get_reserves

get_reserves(
    market: str | None = None,
) -> list[KaminoReserve]

List reserves (token pools) for a lending market.

Parameters:

Name Type Description Default
market str | None

Market address (defaults to config market)

None

Returns:

Type Description
list[KaminoReserve]

List of KaminoReserve objects with current metrics

Raises:

Type Description
KaminoAPIError

If the API request fails

find_reserve_by_token

find_reserve_by_token(
    token_symbol: str, market: str | None = None
) -> KaminoReserve | None

Find a reserve by token symbol.

Parameters:

Name Type Description Default
token_symbol str

Token symbol (e.g., "USDC", "SOL")

required
market str | None

Market address (defaults to config market)

None

Returns:

Type Description
KaminoReserve | None

KaminoReserve if found, None otherwise

deposit

deposit(
    reserve: str,
    amount: str,
    market: str | None = None,
    wallet: str | None = None,
) -> KaminoTransactionResponse

Build a deposit (supply) transaction.

Parameters:

Name Type Description Default
reserve str

Reserve address to deposit into

required
amount str

Amount in token units (e.g., "100.5" for 100.5 USDC)

required
market str | None

Market address (defaults to config market)

None
wallet str | None

Wallet address (defaults to config wallet)

None

Returns:

Type Description
KaminoTransactionResponse

KaminoTransactionResponse with base64-encoded unsigned transaction

Raises:

Type Description
KaminoAPIError

If the API request fails

borrow

borrow(
    reserve: str,
    amount: str,
    market: str | None = None,
    wallet: str | None = None,
) -> KaminoTransactionResponse

Build a borrow transaction.

Parameters:

Name Type Description Default
reserve str

Reserve address to borrow from

required
amount str

Amount in token units (e.g., "50.0" for 50 USDC)

required
market str | None

Market address (defaults to config market)

None
wallet str | None

Wallet address (defaults to config wallet)

None

Returns:

Type Description
KaminoTransactionResponse

KaminoTransactionResponse with base64-encoded unsigned transaction

Raises:

Type Description
KaminoAPIError

If the API request fails

repay

repay(
    reserve: str,
    amount: str,
    market: str | None = None,
    wallet: str | None = None,
) -> KaminoTransactionResponse

Build a repay transaction.

Parameters:

Name Type Description Default
reserve str

Reserve address to repay into

required
amount str

Amount in token units (e.g., "50.0" for 50 USDC)

required
market str | None

Market address (defaults to config market)

None
wallet str | None

Wallet address (defaults to config wallet)

None

Returns:

Type Description
KaminoTransactionResponse

KaminoTransactionResponse with base64-encoded unsigned transaction

Raises:

Type Description
KaminoAPIError

If the API request fails

withdraw

withdraw(
    reserve: str,
    amount: str,
    market: str | None = None,
    wallet: str | None = None,
) -> KaminoTransactionResponse

Build a withdraw transaction.

Use amount=U64_MAX ("18446744073709551615") to withdraw all.

Parameters:

Name Type Description Default
reserve str

Reserve address to withdraw from

required
amount str

Amount in token units, or U64_MAX for withdraw-all

required
market str | None

Market address (defaults to config market)

None
wallet str | None

Wallet address (defaults to config wallet)

None

Returns:

Type Description
KaminoTransactionResponse

KaminoTransactionResponse with base64-encoded unsigned transaction

Raises:

Type Description
KaminoAPIError

If the API request fails

KaminoConfig dataclass

KaminoConfig(
    wallet_address: str,
    base_url: str = "https://api.kamino.finance",
    timeout: int = 30,
    market: str = KAMINO_MAIN_MARKET,
)

Configuration for Kamino client.

Attributes:

Name Type Description
wallet_address str

Solana wallet public key (Base58)

base_url str

Kamino API base URL

timeout int

Request timeout in seconds

market str

Default lending market address (defaults to main market)

__post_init__

__post_init__() -> None

Validate configuration.

KaminoAPIError

KaminoAPIError(
    message: str,
    status_code: int,
    endpoint: str | None = None,
    error_code: str | None = None,
    error_data: dict | None = None,
)

Bases: KaminoError

Exception raised for errors in the Kamino API response.

Attributes:

Name Type Description
message

Error message

status_code

HTTP status code of the response

endpoint

The API endpoint that was called

error_code

Kamino-specific error code (e.g., KLEND_RESERVE_NOT_FOUND)

error_data

Parsed error data from the response

KaminoConfigError

KaminoConfigError(
    message: str, parameter: str | None = None
)

Bases: KaminoError

Exception raised for configuration errors.

Attributes:

Name Type Description
message

Error message

parameter

Name of the configuration parameter that caused the error

KaminoError

Bases: Exception

Base exception class for all Kamino connector errors.

KaminoValidationError

KaminoValidationError(
    message: str,
    field: str | None = None,
    value: Any | None = None,
)

Bases: KaminoError

Exception raised for validation errors.

Attributes:

Name Type Description
message

Error message

field

Name of the field that failed validation

value

The invalid value

KaminoMarket dataclass

KaminoMarket(
    address: str,
    name: str = "",
    description: str = "",
    is_primary: bool = False,
    lookup_table: str = "",
)

A Kamino lending market.

Attributes:

Name Type Description
address str

Market account public key (Base58)

name str

Human-readable market name (e.g., "Main Market")

description str

Market description

is_primary bool

Whether this is the primary market

lookup_table str

Address lookup table for the market

from_api_response classmethod

from_api_response(data: dict[str, Any]) -> KaminoMarket

Create from Kamino API market response.

KaminoReserve dataclass

KaminoReserve(
    address: str,
    token_symbol: str = "",
    token_mint: str = "",
    max_ltv: str = "0",
    borrow_apy: str = "0",
    supply_apy: str = "0",
    total_supply: str = "0",
    total_borrow: str = "0",
    total_supply_usd: str = "0",
    total_borrow_usd: str = "0",
)

A reserve (token pool) within a Kamino lending market.

Attributes:

Name Type Description
address str

Reserve account public key (Base58)

token_symbol str

Token symbol (e.g., "USDC", "SOL")

token_mint str

SPL token mint address (Base58)

max_ltv str

Maximum loan-to-value ratio (e.g., "0.8" = 80%)

borrow_apy str

Current borrow APY as decimal string

supply_apy str

Current supply APY as decimal string

total_supply str

Total supplied amount (in token units)

total_borrow str

Total borrowed amount (in token units)

total_supply_usd str

Total supplied in USD

total_borrow_usd str

Total borrowed in USD

from_api_response classmethod

from_api_response(data: dict[str, Any]) -> KaminoReserve

Create from Kamino API reserve metrics response.

KaminoTransactionResponse dataclass

KaminoTransactionResponse(
    transaction: str,
    action: str = "",
    raw_response: dict[str, Any] = dict(),
)

Response from a Kamino transaction endpoint.

The Kamino API returns a base64-encoded unsigned VersionedTransaction ready for signing and submission.

Attributes:

Name Type Description
transaction str

Base64-encoded unsigned Solana VersionedTransaction

action str

The lending action (deposit, borrow, repay, withdraw)

raw_response dict[str, Any]

Full API response for debugging

from_api_response classmethod

from_api_response(
    data: dict[str, Any], action: str = ""
) -> KaminoTransactionResponse

Create from Kamino API transaction response.

Parameters:

Name Type Description Default
data dict[str, Any]

Kamino /ktx/klend/* API response dict

required
action str

The lending action (deposit, borrow, repay, withdraw)

''

Returns:

Type Description
KaminoTransactionResponse

Parsed KaminoTransactionResponse

KaminoReceiptParser

KaminoReceiptParser(**kwargs: Any)

Receipt parser for Kamino Finance lending transactions.

Uses balance-delta approach: compares pre/post token balances in the Solana transaction receipt to extract the actual amounts deposited, borrowed, repaid, or withdrawn.

Initialize KaminoReceiptParser.

Parameters:

Name Type Description Default
**kwargs Any

Keyword arguments from receipt_registry (e.g., chain).

{}

parse_receipt

parse_receipt(receipt: dict[str, Any]) -> dict[str, Any]

Parse a receipt for ReceiptParser protocol compatibility.

Parameters:

Name Type Description Default
receipt dict[str, Any]

Solana transaction receipt dict

required

Returns:

Type Description
dict[str, Any]

Dict with parsed lending data

extract_supply_amounts

extract_supply_amounts(
    receipt: dict[str, Any], token_mint: str | None = None
) -> LendingAmounts | None

Extract supply (deposit) amounts from receipt.

Supply = tokens leaving the wallet (pre > post).

extract_borrow_amounts

extract_borrow_amounts(
    receipt: dict[str, Any], token_mint: str | None = None
) -> LendingAmounts | None

Extract borrow amounts from receipt.

Borrow = tokens arriving at the wallet (post > pre).

extract_repay_amounts

extract_repay_amounts(
    receipt: dict[str, Any], token_mint: str | None = None
) -> LendingAmounts | None

Extract repay amounts from receipt.

Repay = tokens leaving the wallet (pre > post).

extract_withdraw_amounts

extract_withdraw_amounts(
    receipt: dict[str, Any], token_mint: str | None = None
) -> LendingAmounts | None

Extract withdraw amounts from receipt.

Withdraw = tokens arriving at the wallet (post > pre).