Endpoints to retrieve information about the state of Kamino Earn Vaults
Kamino API (1.0.0)
The Kamino API provides a comprehensive way to interact with Kamino without reading directly from the blockchain.
The API also provides the ability to fetch data that might not be available from just reading the chain.
Kamino products covered by this documentation:
- Kamino Earn Vaults (kvaults)
- Kamino Borrow (klend) (checkout out the SDK examples too)
- Kamino Liquidity (yvaults) (coming soon, in the meantime, checkout out the SDK examples)
The API is rate-limited for unauthenticated users. If you feel you need to make more requests or run into rate-limit issues, please reach out.
🌱 Deposit
Get unsigned Solana transactions to deposit into Kamino Earn Vaults
import {
address,
Address,
addSignersToTransactionMessage,
CompiledTransactionMessage,
createSolanaRpc,
createSolanaRpcSubscriptions,
decompileTransactionMessageFetchingLookupTables, generateKeyPairSigner,
getCompiledTransactionMessageDecoder,
getSignatureFromTransaction,
getTransactionDecoder,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
Signature,
signTransactionMessageWithSigners,
TransactionMessageBytes,
TransactionSigner
} from '@solana/kit';
async function fetchTx(wallet: Address, kvault: Address, amount: number): Promise<TransactionMessageBytes> {
const resp = await fetch(
`https://api.kamino.finance/ktx/kvault/deposit`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
wallet: `${wallet}`,
kvault: `${kvault}`,
amount: amount.toString()
})
}
);
const data = (await resp.json()) as { transaction: string };
const txBuffer = Buffer.from(data.transaction, 'base64');
return getTransactionDecoder().decode(txBuffer).messageBytes;
}
async function signAndSendTx(wallet: TransactionSigner, txBytes: TransactionMessageBytes): Promise<Signature> {
const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');
const dMessage: CompiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(txBytes);
const bh = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
const tx = await pipe(
await decompileTransactionMessageFetchingLookupTables(dMessage, rpc),
(tx) => setTransactionMessageLifetimeUsingBlockhash(bh.value, tx),
(tx) => setTransactionMessageFeePayerSigner(wallet, tx),
(tx) => addSignersToTransactionMessage([wallet], tx),
(tx) => signTransactionMessageWithSigners(tx)
);
const encodedTxMessage = Buffer.from(tx.messageBytes).toString('base64');
console.log(`🔍 Simulation URL: https://explorer.solana.com/tx/inspector?message=${encodeURIComponent(encodedTxMessage)}&cluster=mainnet-beta&signatures=${encodeURIComponent(`[${wallet}]`)}`);
const sig = getSignatureFromTransaction(tx);
console.log(`Sending tx with signature: https://solscan.io/tx/${sig}`);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(tx, {
commitment: 'confirmed',
preflightCommitment: 'confirmed',
maxRetries: 0n,
skipPreflight: true,
minContextSlot: bh.context.slot,
});
console.log(`✅ Tx sent successfully`)
return sig;
}
async function main() {
const wallet = await generateKeyPairSigner();
// Neutral Trade USDC Max Yield Vault
const vault = address('67dqmR76uAbjX6e81A1ganKv3ou31WUMEdeWJkwVfeXy');
// 100 USDC
const depositAmount = 100.0;
console.log(`Using temporary wallet: ${wallet.address} to deposit into vault: ${vault}`);
const tx = await fetchTx(wallet.address, vault, depositAmount);
await signAndSendTx(wallet, tx);
}
main().then(() => `⚡️Deposit transaction complete`).catch((err) => console.error(err));🏃♂️ Withdraw
Get unsigned Solana transactions to withdraw from Kamino Earn Vaults
import {
address,
Address,
addSignersToTransactionMessage,
CompiledTransactionMessage,
createSolanaRpc,
createSolanaRpcSubscriptions,
decompileTransactionMessageFetchingLookupTables, generateKeyPairSigner,
getCompiledTransactionMessageDecoder,
getSignatureFromTransaction,
getTransactionDecoder,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
Signature,
signTransactionMessageWithSigners,
TransactionMessageBytes,
TransactionSigner
} from '@solana/kit';
async function fetchTx(wallet: Address, kvault: Address, amount: number): Promise<TransactionMessageBytes> {
const resp = await fetch(
`https://api.kamino.finance/ktx/kvault/withdraw`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
wallet: `${wallet}`,
kvault: `${kvault}`,
amount: amount.toString()
})
}
);
const data = (await resp.json()) as { transaction: string };
const txBuffer = Buffer.from(data.transaction, 'base64');
return getTransactionDecoder().decode(txBuffer).messageBytes;
}
async function signAndSendTx(wallet: TransactionSigner, txBytes: TransactionMessageBytes): Promise<Signature> {
const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');
const dMessage: CompiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(txBytes);
const bh = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
const tx = await pipe(
await decompileTransactionMessageFetchingLookupTables(dMessage, rpc),
(tx) => setTransactionMessageLifetimeUsingBlockhash(bh.value, tx),
(tx) => setTransactionMessageFeePayerSigner(wallet, tx),
(tx) => addSignersToTransactionMessage([wallet], tx),
(tx) => signTransactionMessageWithSigners(tx)
);
const encodedTxMessage = Buffer.from(tx.messageBytes).toString('base64');
console.log(`🔍 Simulation URL: https://explorer.solana.com/tx/inspector?message=${encodeURIComponent(encodedTxMessage)}&cluster=mainnet-beta&signatures=${encodeURIComponent(`[${wallet}]`)}`);
const sig = getSignatureFromTransaction(tx);
console.log(`Sending tx with signature: https://solscan.io/tx/${sig}`);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(tx, {
commitment: 'confirmed',
preflightCommitment: 'confirmed',
maxRetries: 0n,
skipPreflight: true,
minContextSlot: bh.context.slot,
});
console.log(`✅ Tx sent successfully`)
return sig;
}
async function main() {
const wallet = await generateKeyPairSigner();
// Neutral Trade USDC Max Yield Vault
const vault = address('67dqmR76uAbjX6e81A1ganKv3ou31WUMEdeWJkwVfeXy');
// 50 USDC
const withdrawAmount = 50.0;
console.log(`Using temporary wallet: ${wallet.address} to withdraw from vault: ${vault}`);
const tx = await fetchTx(wallet.address, vault, withdrawAmount);
await signAndSendTx(wallet, tx);
}
main().then(() => `⚡️Withdrawal transaction complete`).catch((err) => console.error(err));📝 Deposit
Get unsigned Solana transactions to deposit liquidity into a Kamino Lend market reserve, which can then be used as collateral to borrow
import {
address,
Address,
addSignersToTransactionMessage,
CompiledTransactionMessage,
createSolanaRpc,
createSolanaRpcSubscriptions,
decompileTransactionMessageFetchingLookupTables, generateKeyPairSigner,
getCompiledTransactionMessageDecoder,
getSignatureFromTransaction,
getTransactionDecoder,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
Signature,
signTransactionMessageWithSigners,
TransactionMessageBytes,
TransactionSigner
} from '@solana/kit';
async function fetchTx(wallet: Address, market: Address, reserve: Address, amount: number): Promise<TransactionMessageBytes> {
const resp = await fetch(
`https://api.kamino.finance/ktx/klend/deposit`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
wallet: `${wallet}`,
market: `${market}`,
reserve: `${reserve}`,
amount: amount.toString()
})
}
);
const data = (await resp.json()) as { transaction: string };
const txBuffer = Buffer.from(data.transaction, 'base64');
return getTransactionDecoder().decode(txBuffer).messageBytes;
}
async function signAndSendTx(wallet: TransactionSigner, txBytes: TransactionMessageBytes): Promise<Signature> {
const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');
const dMessage: CompiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(txBytes);
const bh = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
const tx = await pipe(
await decompileTransactionMessageFetchingLookupTables(dMessage, rpc),
(tx) => setTransactionMessageLifetimeUsingBlockhash(bh.value, tx),
(tx) => setTransactionMessageFeePayerSigner(wallet, tx),
(tx) => addSignersToTransactionMessage([wallet], tx),
(tx) => signTransactionMessageWithSigners(tx)
);
const encodedTxMessage = Buffer.from(tx.messageBytes).toString('base64');
console.log(`🔍 Simulation URL: https://explorer.solana.com/tx/inspector?message=${encodeURIComponent(encodedTxMessage)}&cluster=mainnet-beta&signatures=${encodeURIComponent(`[${wallet}]`)}`);
const sig = getSignatureFromTransaction(tx);
console.log(`Sending tx with signature: https://solscan.io/tx/${sig}`);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(tx, {
commitment: 'confirmed',
preflightCommitment: 'confirmed',
maxRetries: 0n,
skipPreflight: true,
minContextSlot: bh.context.slot,
});
console.log(`✅ Tx sent successfully`)
return sig;
}
async function main() {
const wallet = await generateKeyPairSigner();
// Main market
const market = address('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
// USDC reserve in main market
const reserve = address('D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59');
// 50 USDC
const depositAmount = 50.0;
console.log(`Using temporary wallet: ${wallet.address} to deposit into market: ${market}, reserve: ${reserve}`);
const tx = await fetchTx(wallet.address, market, reserve, depositAmount);
await signAndSendTx(wallet, tx);
}
main().then(() => `⚡️Deposit transaction complete`).catch((err) => console.error(err));💳 Borrow
Get unsigned Solana transactions to borrow liquidity from a given Kamino Lend market reserve
import {
address,
Address,
addSignersToTransactionMessage,
CompiledTransactionMessage,
createSolanaRpc,
createSolanaRpcSubscriptions,
decompileTransactionMessageFetchingLookupTables, generateKeyPairSigner,
getCompiledTransactionMessageDecoder,
getSignatureFromTransaction,
getTransactionDecoder,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
Signature,
signTransactionMessageWithSigners,
TransactionMessageBytes,
TransactionSigner
} from '@solana/kit';
async function fetchTx(wallet: Address, market: Address, reserve: Address, amount: number): Promise<TransactionMessageBytes> {
const resp = await fetch(
`https://api.kamino.finance/ktx/klend/borrow`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
wallet: `${wallet}`,
market: `${market}`,
reserve: `${reserve}`,
amount: amount.toString()
})
}
);
const data = (await resp.json()) as { transaction: string };
const txBuffer = Buffer.from(data.transaction, 'base64');
return getTransactionDecoder().decode(txBuffer).messageBytes;
}
async function signAndSendTx(wallet: TransactionSigner, txBytes: TransactionMessageBytes): Promise<Signature> {
const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');
const dMessage: CompiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(txBytes);
const bh = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
const tx = await pipe(
await decompileTransactionMessageFetchingLookupTables(dMessage, rpc),
(tx) => setTransactionMessageLifetimeUsingBlockhash(bh.value, tx),
(tx) => setTransactionMessageFeePayerSigner(wallet, tx),
(tx) => addSignersToTransactionMessage([wallet], tx),
(tx) => signTransactionMessageWithSigners(tx)
);
const encodedTxMessage = Buffer.from(tx.messageBytes).toString('base64');
console.log(`🔍 Simulation URL: https://explorer.solana.com/tx/inspector?message=${encodeURIComponent(encodedTxMessage)}&cluster=mainnet-beta&signatures=${encodeURIComponent(`[${wallet}]`)}`);
const sig = getSignatureFromTransaction(tx);
console.log(`Sending tx with signature: https://solscan.io/tx/${sig}`);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(tx, {
commitment: 'confirmed',
preflightCommitment: 'confirmed',
maxRetries: 0n,
skipPreflight: true,
minContextSlot: bh.context.slot,
});
console.log(`✅ Tx sent successfully`)
return sig;
}
async function main() {
const wallet = await generateKeyPairSigner();
// Main market
const market = address('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
// USDC reserve in main market
const reserve = address('D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59');
// 50 USDC
const borrowAmount = 50.0;
console.log(`Using temporary wallet: ${wallet.address} to borrow from market: ${market}, reserve: ${reserve}`);
const tx = await fetchTx(wallet.address, market, reserve, borrowAmount);
await signAndSendTx(wallet, tx);
}
main().then(() => `⚡️Borrow transaction complete`).catch((err) => console.error(err));📝 Repay
Get unsigned Solana transactions to repay debt for a given Kamino Lend user position
import {
address,
Address,
addSignersToTransactionMessage,
CompiledTransactionMessage,
createSolanaRpc,
createSolanaRpcSubscriptions,
decompileTransactionMessageFetchingLookupTables, generateKeyPairSigner,
getCompiledTransactionMessageDecoder,
getSignatureFromTransaction,
getTransactionDecoder,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
Signature,
signTransactionMessageWithSigners,
TransactionMessageBytes,
TransactionSigner
} from '@solana/kit';
async function fetchTx(wallet: Address, market: Address, reserve: Address, amount: number): Promise<TransactionMessageBytes> {
const resp = await fetch(
`https://api.kamino.finance/ktx/klend/repay`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
wallet: `${wallet}`,
market: `${market}`,
reserve: `${reserve}`,
amount: amount.toString()
})
}
);
const data = (await resp.json()) as { transaction: string };
const txBuffer = Buffer.from(data.transaction, 'base64');
return getTransactionDecoder().decode(txBuffer).messageBytes;
}
async function signAndSendTx(wallet: TransactionSigner, txBytes: TransactionMessageBytes): Promise<Signature> {
const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');
const dMessage: CompiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(txBytes);
const bh = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
const tx = await pipe(
await decompileTransactionMessageFetchingLookupTables(dMessage, rpc),
(tx) => setTransactionMessageLifetimeUsingBlockhash(bh.value, tx),
(tx) => setTransactionMessageFeePayerSigner(wallet, tx),
(tx) => addSignersToTransactionMessage([wallet], tx),
(tx) => signTransactionMessageWithSigners(tx)
);
const encodedTxMessage = Buffer.from(tx.messageBytes).toString('base64');
console.log(`🔍 Simulation URL: https://explorer.solana.com/tx/inspector?message=${encodeURIComponent(encodedTxMessage)}&cluster=mainnet-beta&signatures=${encodeURIComponent(`[${wallet}]`)}`);
const sig = getSignatureFromTransaction(tx);
console.log(`Sending tx with signature: https://solscan.io/tx/${sig}`);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(tx, {
commitment: 'confirmed',
preflightCommitment: 'confirmed',
maxRetries: 0n,
skipPreflight: true,
minContextSlot: bh.context.slot,
});
console.log(`✅ Tx sent successfully`)
return sig;
}
async function main() {
const wallet = await generateKeyPairSigner();
// Main market
const market = address('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
// USDC reserve in main market
const reserve = address('D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59');
// 50 USDC
const repayAmount = 50.0;
console.log(`Using temporary wallet: ${wallet.address} to repay debt from market: ${market}, reserve: ${reserve}`);
const tx = await fetchTx(wallet.address, market, reserve, repayAmount);
await signAndSendTx(wallet, tx);
}
main().then(() => `⚡️Repay transaction complete`).catch((err) => console.error(err));🐝 Withdraw
Get unsigned Solana transactions to withdraw liquidity from a given Kamino Lend market reserve
import {
address,
Address,
addSignersToTransactionMessage,
CompiledTransactionMessage,
createSolanaRpc,
createSolanaRpcSubscriptions,
decompileTransactionMessageFetchingLookupTables, generateKeyPairSigner,
getCompiledTransactionMessageDecoder,
getSignatureFromTransaction,
getTransactionDecoder,
pipe,
sendAndConfirmTransactionFactory,
setTransactionMessageFeePayerSigner,
setTransactionMessageLifetimeUsingBlockhash,
Signature,
signTransactionMessageWithSigners,
TransactionMessageBytes,
TransactionSigner
} from '@solana/kit';
async function fetchTx(wallet: Address, market: Address, reserve: Address, amount: number): Promise<TransactionMessageBytes> {
const resp = await fetch(
`https://api.kamino.finance/ktx/klend/withdraw`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
wallet: `${wallet}`,
market: `${market}`,
reserve: `${reserve}`,
amount: amount.toString()
})
}
);
const data = (await resp.json()) as { transaction: string };
const txBuffer = Buffer.from(data.transaction, 'base64');
return getTransactionDecoder().decode(txBuffer).messageBytes;
}
async function signAndSendTx(wallet: TransactionSigner, txBytes: TransactionMessageBytes): Promise<Signature> {
const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');
const dMessage: CompiledTransactionMessage = getCompiledTransactionMessageDecoder().decode(txBytes);
const bh = await rpc.getLatestBlockhash({ commitment: 'finalized' }).send();
const tx = await pipe(
await decompileTransactionMessageFetchingLookupTables(dMessage, rpc),
(tx) => setTransactionMessageLifetimeUsingBlockhash(bh.value, tx),
(tx) => setTransactionMessageFeePayerSigner(wallet, tx),
(tx) => addSignersToTransactionMessage([wallet], tx),
(tx) => signTransactionMessageWithSigners(tx)
);
const encodedTxMessage = Buffer.from(tx.messageBytes).toString('base64');
console.log(`🔍 Simulation URL: https://explorer.solana.com/tx/inspector?message=${encodeURIComponent(encodedTxMessage)}&cluster=mainnet-beta&signatures=${encodeURIComponent(`[${wallet}]`)}`);
const sig = getSignatureFromTransaction(tx);
console.log(`Sending tx with signature: https://solscan.io/tx/${sig}`);
await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(tx, {
commitment: 'confirmed',
preflightCommitment: 'confirmed',
maxRetries: 0n,
skipPreflight: true,
minContextSlot: bh.context.slot,
});
console.log(`✅ Tx sent successfully`)
return sig;
}
async function main() {
const wallet = await generateKeyPairSigner();
// Main market
const market = address('7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF');
// USDC reserve in main market
const reserve = address('D6q6wuQSrifJKZYpR1M8R4YawnLDtDsMmWM1NbBmgJ59');
// 50 USDC
const withdrawAmount = 50.0;
console.log(`Using temporary wallet: ${wallet.address} to withdraw from market: ${market}, reserve: ${reserve}`);
const tx = await fetchTx(wallet.address, market, reserve, withdrawAmount);
await signAndSendTx(wallet, tx);
}
main().then(() => `⚡️Withdraw transaction complete`).catch((err) => console.error(err));