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
¶
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 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 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 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 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
¶
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 |
get_markets
¶
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
¶
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 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) |
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
¶
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
¶
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
¶
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
¶
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
¶
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
¶
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 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).