Security News
tea.xyz Spam Plagues npm and RubyGems Package Registries
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
@marinade.finance/kamino-sdk
Advanced tools
Readme
Kamino SDK is a TypeScript client SDK for easy access to the Kamino on-chain data.
npm install @solana/web3.js decimal.js @hubbleprotocol/kamino-sdk
To read kamino-specific on-chain data, you may use the following methods:
import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js';
import { Kamino } from '@hubbleprotocol/kamino-sdk';
const connection = new Connection(clusterApiUrl('mainnet-beta'));
const kamino = new Kamino('mainnet-beta', connection);
// get all strategies supported by Kamino
const strategies = await kamino.getStrategies();
// get specific strategy
const customStrategy = await kamino.getStrategyByAddress(new PublicKey('my strategy address'));
// get strategy share price
const sharePrice = await kamino.getStrategySharePrice(new PublicKey('my strategy address'));
// get token holders of a strategy
const holders = await kamino.getStrategyHolders(usdhUsdtStrategy);
// get strategy share price
const strategyPrice = await kamino.getStrategySharePrice(usdhUsdtStrategy);
Create a new Kamino strategy for an existing CLMM pool (Orca or Raydium).
Current limitations (planned to be fixed to allow anyone to use this in the near future):
import { clusterApiUrl, Connection, PublicKey, sendAndConfirmTransaction, Keypair, Transaction } from '@solana/web3.js';
import {
Kamino,
getAssociatedTokenAddressAndData,
createTransactionWithExtraBudget,
assignBlockInfoToTransaction
} from '@hubbleprotocol/kamino-sdk';
import Decimal from 'decimal.js';
// generate a new strategy public key
const newStrategy = Keypair.generate();
// setup fee payer (wallet) that will sign the transaction and own the strategy
const signer = Keypair.fromSecretKey('your secret key here');
const owner = signer.publicKey; // or use different public key for owner (admin)
// setup Kamino SDK
const connection = new Connection(clusterApiUrl('mainnet-beta'));
const kamino = new Kamino('mainnet-beta', connection);
// depending on the DEX you want to use for your strategy (Orca or Raydium) fetch the pool
// Orca: get on-chain data for an existing Orca Whirlpool
const whirlpool = new PublicKey('5vHht2PCHKsApekfPZXyn7XthAYQbsCNiwA1VEcQmL12');
const whirlpoolState = await kamino.getWhirlpoolByAddress(whirlpool);
if (!whirlpool) {
throw Error('Could not fetch Orca whirlpool from the chain');
}
// Raydium: get on-chain data for an existing Raydium CLMM pool
const raydiumPool = new PublicKey('3tD34VtprDSkYCnATtQLCiVgTkECU3d12KtjupeR6N2X');
const raydiumPoolState = await kamino.getWhirlpoolByAddress(raydiumPool);
if (!raydiumPool) {
throw Error('Could not fetch Raydium CLMM pool from the chain');
}
// create a transaction that has an instruction for extra compute budget
let tx = createTransactionWithExtraBudget(owner);
// check if associated token addresses exist for token A or B
const [tokenAAta, tokenAData] = await getAssociatedTokenAddressAndData(connection, whirlpoolState.tokenAMint, owner);
const [tokenBAta, tokenBData] = await getAssociatedTokenAddressAndData(connection, whirlpoolState.tokenBMint, owner);
if (!tokenAData) {
tx.add(createAssociatedTokenAccountInstruction(owner, tokenAAta, owner, whirlpoolState.tokenMintA));
}
if (!tokenBData) {
tx.add(createAssociatedTokenAccountInstruction(owner, tokenBAta, owner, whirlpoolState.tokenMintB));
}
// create a rent exempt strategy account that will contain the Kamino strategy
const createStrategyAccountIx = await kamino.createStrategyAccount(owner, newStrategy.publicKey);
tx.add(createStrategyAccountIx);
// create the actual strategy with USDH as token A and USDC as token B (note: the tokens in the pool should match the tokens in the strategy)
const createStrategyIx = await kamino.createStrategy(newStrategy.publicKey, whirlpool, owner, 'USDH', 'USDC');
tx.add(createStrategyIx);
tx = await assignBlockInfoToTransaction(connection, tx, owner);
const txHash = await sendAndConfirmTransaction(connection, tx, [signer, newStrategy], {
commitment: 'finalized',
});
console.log('transaction hash', txHash);
console.log('new strategy has been created', newStrategy.publicKey.toString());
// this will work with 'finalized' transaction commitment level,
// it might fail if you use anything other than that as the on-chain data won't be updated as quickly
// and you have to wait a bit
const strategy = await kamino.getStrategyByAddress(newStrategy.publicKey);
console.log(strategy?.toJSON());
Withdraw x amount of strategy shares from a specific shareholder (wallet), example code:
import { clusterApiUrl, Connection, PublicKey, sendAndConfirmTransaction, Keypair, Transaction } from '@solana/web3.js';
import {
Kamino,
getAssociatedTokenAddressAndData,
createTransactionWithExtraBudget,
getCreateAssociatedTokenAccountInstructionsIfNotExist,
assignBlockInfoToTransaction
} from '@hubbleprotocol/kamino-sdk';
import Decimal from 'decimal.js';
// setup Kamino SDK
const strategyPubkey = new PublicKey('2H4xebnp2M9JYgPPfUw58uUQahWF8f1YTNxwwtmdqVYV'); // you may also fetch strategies from hubble config
const owner = new PublicKey('HrwbdQYwSnAyVpVHuGQ661HiNbWmGjDp5DdDR9YMw7Bu'); // wallet with shares
const connection = new Connection(clusterApiUrl('mainnet-beta'));
const kamino = new Kamino('mainnet-beta', connection);
// setup fee payer (wallet) that will sign the transaction
const signer = Keypair.generate();
// get on-chain data for a Kamino strategy
const strategy = await kamino.getStrategyByAddress(strategyPubkey);
if (!strategy) {
throw Error('Could not fetch strategy from the chain');
}
const strategyWithAddress = { strategy, address: strategyPubkey };
// check if associated token addresses exist for token A, B and shares
const [sharesAta, sharesMintData] = await getAssociatedTokenAddressAndData(connection, strategy.sharesMint, owner);
const [tokenAAta, tokenAData] = await getAssociatedTokenAddressAndData(connection, strategy.tokenAMint, owner);
const [tokenBAta, tokenBData] = await getAssociatedTokenAddressAndData(connection, strategy.tokenBMint, owner);
// create a transaction that has an instruction for extra compute budget (withdraw operation needs this),
let tx = createTransactionWithExtraBudget(owner);
// add creation of associated token addresses to the transaction instructions if they don't exist
const ataInstructions = await kamino.getCreateAssociatedTokenAccountInstructionsIfNotExist(
owner,
strategyWithAddress,
tokenAData,
tokenAAta,
tokenBData,
tokenBAta,
sharesMintData,
sharesAta
);
if (ataInstructions.length > 0) {
tx.add(...ataInstructions);
}
// specify amount of shares to withdraw, e.g. to withdraw 5 shares:
const withdrawIx = await kamino.withdrawShares(strategyWithAddress, new Decimal(5), owner);
tx.add(withdrawIx);
// assign block hash, block height and fee payer to the transaction
tx = await assignBlockInfoToTransaction(connection, tx, signer.publicKey);
const txHash = await sendAndConfirmTransaction(connection, tx, [signer], {
commitment: 'confirmed',
});
Withdraw all strategy shares from a specific shareholder (wallet), example code:
import { clusterApiUrl, Connection, PublicKey, sendAndConfirmTransaction, Keypair, Transaction } from '@solana/web3.js';
import {
Kamino,
getAssociatedTokenAddressAndData,
createTransactionWithExtraBudget,
getCreateAssociatedTokenAccountInstructionsIfNotExist,
assignBlockInfoToTransaction
} from '@hubbleprotocol/kamino-sdk';
import Decimal from 'decimal.js';
// setup Kamino SDK
const strategyPubkey = new PublicKey('2H4xebnp2M9JYgPPfUw58uUQahWF8f1YTNxwwtmdqVYV'); // you may also fetch strategies from hubble config
const owner = new PublicKey('HrwbdQYwSnAyVpVHuGQ661HiNbWmGjDp5DdDR9YMw7Bu'); // wallet to deposit shares into
const connection = new Connection(clusterApiUrl('mainnet-beta'));
const kamino = new Kamino('mainnet-beta', connection);
// setup fee payer (wallet) that will sign the transaction
const signer = Keypair.generate();
// get on-chain data for a Kamino strategy
const strategy = await kamino.getStrategyByAddress(strategyPubkey);
if (!strategy) {
throw Error('Could not fetch strategy from the chain');
}
const strategyWithAddress = { strategy, address: strategyPubkey };
// check if associated token addresses exist for token A, B and shares
const [sharesAta, sharesMintData] = await getAssociatedTokenAddressAndData(connection, strategy.sharesMint, owner);
const [tokenAAta, tokenAData] = await getAssociatedTokenAddressAndData(connection, strategy.tokenAMint, owner);
const [tokenBAta, tokenBData] = await getAssociatedTokenAddressAndData(connection, strategy.tokenBMint, owner);
// create a transaction that has an instruction for extra compute budget (withdraw operation needs this),
let tx = createTransactionWithExtraBudget(owner);
// add creation of associated token addresses to the transaction instructions if they don't exist
const ataInstructions = await kamino.getCreateAssociatedTokenAccountInstructionsIfNotExist(
owner,
strategyWithAddress,
tokenAData,
tokenAAta,
tokenBData,
tokenBAta,
sharesMintData,
sharesAta
);
if (ataInstructions.length > 0) {
tx.add(...ataInstructions);
}
// withdraw all strategy shares from the wallet:
const withdrawIxns = await kamino.withdrawAllShares(strategyWithAddress, owner);
if (withdrawIxns) {
tx.add(...withdrawIxns);
} else {
console.log('Wallet balance is 0 shares, cant withdraw any');
return;
}
// assign block hash, block height and fee payer to the transaction
tx = await assignBlockInfoToTransaction(connection, tx, signer.publicKey);
const txHash = await sendAndConfirmTransaction(connection, tx, [signer], {
commitment: 'confirmed',
});
Deposit custom amount of token A and B for a specific strategy, example code:
import { clusterApiUrl, Connection, PublicKey, sendAndConfirmTransaction, Keypair, Transaction } from '@solana/web3.js';
import {
Kamino,
getAssociatedTokenAddressAndData,
createTransactionWithExtraBudget,
getCreateAssociatedTokenAccountInstructionsIfNotExist,
assignBlockInfoToTransaction
} from '@hubbleprotocol/kamino-sdk';
import Decimal from 'decimal.js';
// setup Kamino SDK
const strategyPubkey = new PublicKey('2H4xebnp2M9JYgPPfUw58uUQahWF8f1YTNxwwtmdqVYV'); // you may also fetch strategies from hubble config
const owner = new PublicKey('HrwbdQYwSnAyVpVHuGQ661HiNbWmGjDp5DdDR9YMw7Bu'); // wallet with shares
const connection = new Connection(clusterApiUrl('mainnet-beta'));
const kamino = new Kamino('mainnet-beta', connection);
// setup fee payer (wallet) that will sign the transaction
const signer = Keypair.generate();
// get on-chain data for a Kamino strategy
const strategy = await kamino.getStrategyByAddress(strategyPubkey);
if (!strategy) {
throw Error('Could not fetch strategy from the chain');
}
const strategyWithAddress = { strategy, address: strategyPubkey };
// check if associated token addresses exist for token A, B and shares
const [sharesAta, sharesMintData] = await getAssociatedTokenAddressAndData(connection, strategy.sharesMint, owner);
const [tokenAAta, tokenAData] = await getAssociatedTokenAddressAndData(connection, strategy.tokenAMint, owner);
const [tokenBAta, tokenBData] = await getAssociatedTokenAddressAndData(connection, strategy.tokenBMint, owner);
// create a transaction that has an instruction for extra compute budget (deposit operation needs this),
let tx = createTransactionWithExtraBudget(owner);
// add creation of associated token addresses to the transaction instructions if they don't exist
const ataInstructions = await kamino.getCreateAssociatedTokenAccountInstructionsIfNotExist(
owner,
strategyWithAddress,
tokenAData,
tokenAAta,
tokenBData,
tokenBAta,
sharesMintData,
sharesAta
);
if (ataInstructions.length > 0) {
tx.add(...ataInstructions);
}
// specify amount of token A and B to deposit, e.g. to deposit 5 USDH and 5 USDC:
const depositIx = await kamino.deposit(strategyWithAddress, new Decimal(5), new Decimal(5), owner);
tx.add(depositIx);
// assign block hash, block height and fee payer to the transaction
tx = await assignBlockInfoToTransaction(connection, tx, signer.publicKey);
const txHash = await sendAndConfirmTransaction(connection, tx, [signer], {
commitment: 'confirmed',
});
Collect strategy fees from the treasury fee vaults and rewards from the reward vaults:
import { clusterApiUrl, Connection, PublicKey, sendAndConfirmTransaction, Keypair, Transaction } from '@solana/web3.js';
import {
Kamino,
createTransactionWithExtraBudget,
assignBlockInfoToTransaction
} from '@hubbleprotocol/kamino-sdk';
import Decimal from 'decimal.js';
// setup Kamino SDK
const strategyPubkey = new PublicKey('2H4xebnp2M9JYgPPfUw58uUQahWF8f1YTNxwwtmdqVYV'); // you may also fetch strategies from hubble config
const owner = new PublicKey('HrwbdQYwSnAyVpVHuGQ661HiNbWmGjDp5DdDR9YMw7Bu'); // strategy owner
const connection = new Connection(clusterApiUrl('mainnet-beta'));
const kamino = new Kamino('mainnet-beta', connection);
// setup fee payer (wallet) that will sign the transaction
const signer = Keypair.generate();
// create a transaction that has an instruction for extra compute budget
let tx = createTransactionWithExtraBudget(owner);
// get on-chain data for a Kamino strategy
const strategy = await kamino.getStrategyByAddress(strategyPubkey);
if (!strategy) {
throw Error('Could not fetch strategy from the chain');
}
const strategyWithAddress = { strategy, address: strategyPubkey };
// create collect fee/rewards instructions
const collectIx = await kamino.collectFeesAndRewards(strategyWithAddress);
tx.add(collectIx);
// assign block hash, block height and fee payer to the transaction
tx = await assignBlockInfoToTransaction(connection, tx, signer.publicKey);
const txHash = await sendAndConfirmTransaction(connection, tx, [signer], {
commitment: 'confirmed',
});
import { clusterApiUrl, Connection, PublicKey, sendAndConfirmTransaction, Keypair, Transaction } from '@solana/web3.js';
import {
Kamino,
createTransactionWithExtraBudget,
assignBlockInfoToTransaction
} from '@hubbleprotocol/kamino-sdk';
import Decimal from 'decimal.js';
// setup Kamino SDK
const strategyPubkey = new PublicKey('2H4xebnp2M9JYgPPfUw58uUQahWF8f1YTNxwwtmdqVYV'); // you may also fetch strategies from hubble config
const owner = new PublicKey('HrwbdQYwSnAyVpVHuGQ661HiNbWmGjDp5DdDR9YMw7Bu'); // strategy owner
const connection = new Connection(clusterApiUrl('mainnet-beta'));
const kamino = new Kamino('mainnet-beta', connection);
// setup fee payer (wallet) that will sign the transaction
const signer = Keypair.generate();
// setup new position mint
const newPosition = Keypair.generate();
// create a transaction that has an instruction for extra compute budget
let tx = createTransactionWithExtraBudget(owner);
// rebalance a USDH-USDC strategy to range 0.9 - 1.1
const rebalanceInstructions = await kamino.rebalance(
strategy,
newPosition.publicKey,
new Decimal(0.9),
new Decimal(1.1),
signer.publicKey
);
for (const rebalanceInstruction of rebalanceInstructions) {
let tx = new Transaction();
// assign block hash, block height and fee payer to the transaction
tx = await assignBlockInfoToTransaction(connection, tx, owner);
const txHash = await sendAndConfirmTransaction(connection, tx, [signer, newPosition], {
commitment: 'finalized',
});
console.log('transaction hash', txHash);
}
strategyType
which can be:
NON_PEGGED
: e.g. SOL-BONKPEGGED
: e.g. BSOL-JitoSOLSTABLE
: e.g. USDH-USDCstrategyCreationStatus
which can be:
IGNORED
SHADOW
LIVE
DEPRECATED
STAGING
import { clusterApiUrl, Connection, PublicKey, sendAndConfirmTransaction, Keypair, Transaction } from '@solana/web3.js';
import {
Kamino,
createTransactionWithExtraBudget,
assignBlockInfoToTransaction,
StrategiesFilters
} from '@hubbleprotocol/kamino-sdk';
import Decimal from 'decimal.js';
// create a Kamino instance
const kamino = new Kamino('mainnet-beta', connection);
// get all Kamino strategies that are non_pegged
let filters: StrategiesFilters = {
strategyType: 'NON_PEGGED',
strategyCreationStatus: undefined,
};
let nonPeggedStrats = await kamino.getAllStrategiesWithFilters(filters);
FAQs
Kamino SDK
The npm package @marinade.finance/kamino-sdk receives a total of 0 weekly downloads. As such, @marinade.finance/kamino-sdk popularity was classified as not popular.
We found that @marinade.finance/kamino-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Tea.xyz, a crypto project aimed at rewarding open source contributions, is once again facing backlash due to an influx of spam packages flooding public package registries.
Security News
As cyber threats become more autonomous, AI-powered defenses are crucial for businesses to stay ahead of attackers who can exploit software vulnerabilities at scale.
Security News
UnitedHealth Group disclosed that the ransomware attack on Change Healthcare compromised protected health information for millions in the U.S., with estimated costs to the company expected to reach $1 billion.