Documentation Index Fetch the complete documentation index at: https://kamino.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Refer User Without Deposit
Create a UserMetadata account with a referrer without requiring an initial deposit. This allows you to link a referrer to a user before they perform any lending operations.
The referrer must be set when the UserMetadata account is created and cannot be changed afterward.
Import Dependencies Import the required packages for Solana RPC communication, Kamino SDK operations, and Kit transaction building. import {
createSolanaRpc ,
createSolanaRpcSubscriptions ,
address ,
pipe ,
createTransactionMessage ,
setTransactionMessageFeePayerSigner ,
setTransactionMessageLifetimeUsingBlockhash ,
appendTransactionMessageInstructions ,
signTransactionMessageWithSigners ,
sendAndConfirmTransactionFactory ,
getSignatureFromTransaction ,
some ,
} from '@solana/kit' ;
import { KaminoMarket , getUserLutAddressAndSetupIxs , parseKeypairFile } from '@kamino-finance/klend-sdk' ;
Initialize RPC and Load Market Set up configuration constants and initialize RPC connections. const KEYPAIR_FILE = '/path/to/your/keypair.json' ;
const REFERRER = address ( 'EZC9wzVCvihCsCHEMGADYdsRhcpdRYWzSCfqY' );
const MARKET_PUBKEY = address ( '7u3HeHxYDLhnCoErrtycNokbQYbWGzLs6JSDqGAv5PfF' );
const RPC_ENDPOINT = 'https://api.mainnet-beta.solana.com' ;
const WS_ENDPOINT = 'wss://api.mainnet-beta.solana.com' ;
const signer = await parseKeypairFile ( KEYPAIR_FILE );
const rpc = createSolanaRpc ( RPC_ENDPOINT );
const rpcSubscriptions = createSolanaRpcSubscriptions ( WS_ENDPOINT );
const market = await KaminoMarket . load ( rpc , MARKET_PUBKEY , 400 );
Update the REFERRER address with the wallet address of the referrer who will earn commission from the user’s borrowing activity.
Verify that UserMetadata does not already exist for the user. const [, existingUserMetadata ] = await market ! . getUserMetadata ( signer . address );
if ( existingUserMetadata ) {
throw new Error ( 'UserMetadata already created - referrer cannot be changed!' );
}
Once UserMetadata is created with a referrer, the referrer cannot be changed. Always check if UserMetadata exists before attempting to create it.
Generate instructions to create the UserMetadata account with the referrer. const [, setupIxsArray ] = await getUserLutAddressAndSetupIxs (
market ! ,
signer ,
some ( REFERRER ),
false ,
[],
[]
);
const instructions = setupIxsArray . flat ();
getUserLutAddressAndSetupIxs creates the necessary instructions to set up UserMetadata with a referrer without requiring a deposit operation.
Build and Sign Transaction Build the transaction using Kit’s functional pipe pattern. const { value : blockhash } = await rpc . getLatestBlockhash ({ commitment: 'finalized' }). send ();
const tx = pipe (
createTransactionMessage ({ version: 0 }),
( tx ) => setTransactionMessageFeePayerSigner ( signer , tx ),
( tx ) => setTransactionMessageLifetimeUsingBlockhash ( blockhash , tx ),
( tx ) => appendTransactionMessageInstructions ( instructions , tx )
);
const signed = await signTransactionMessageWithSigners ( tx );
Send and Confirm Transaction Send the transaction and confirm it using WebSocket. const signature = getSignatureFromTransaction ( signed );
await sendAndConfirmTransactionFactory ({ rpc , rpcSubscriptions })( signed , {
commitment: 'confirmed' ,
skipPreflight: true ,
});
console . log ( 'UserMetadata created with referrer' );
console . log ( `Signature: ${ signature } ` );
UserMetadata creation complete. The referrer is now permanently linked to the user and will earn commission from the user’s future borrowing activity.
klend-interface is a lightweight Rust instruction builder — it creates Vec<Instruction> with required refresh instructions prepended automatically. Use ReserveInfo::from_account_data(pubkey, &data) to construct reserve info from raw RPC account bytes. For obligation-based operations, ObligationContext is the recommended approach — it fetches the obligation and its associated reserves, then provides convenient .deposit(), .borrow(), .repay(), and .withdraw() methods.
Add Dependencies [ dependencies ]
klend-interface = "0.1.0"
solana-pubkey = "2.1"
solana-instruction = "2.1"
solana-sdk = "~2.3"
solana-client = "~2.3"
spl-token = "7"
spl-associated-token-account = "6"
Set Up RPC Client use solana_client :: rpc_client :: RpcClient ;
use solana_sdk :: signer :: keypair :: read_keypair_file;
use solana_sdk :: signer :: Signer ;
let rpc_client = RpcClient :: new ( "https://api.mainnet-beta.solana.com" );
let signer = read_keypair_file ( "/path/to/your/keypair.json" )
. expect ( "Failed to read keypair file" );
let owner = signer . pubkey ();
Derive PDAs and Build Instruction Create the init_user_metadata instruction linking the user to a referrer without requiring a deposit. use klend_interface :: instructions :: referrer :: {
init_user_metadata,
InitUserMetadataAccounts ,
};
use klend_interface :: pda;
use klend_interface :: KLEND_PROGRAM_ID ;
use solana_pubkey :: Pubkey ;
use std :: str :: FromStr ;
let referrer = Pubkey :: from_str ( "EZC9wzVCvihCsCHEMGADYdsRhcpdRYWzSCfqY" ) . unwrap ();
// Derive PDAs
let ( user_metadata , _ ) = pda :: user_metadata ( & KLEND_PROGRAM_ID , & owner );
let ( referrer_user_metadata , _ ) = pda :: user_metadata ( & KLEND_PROGRAM_ID , & referrer );
// Your user's address lookup table (created during onboarding)
let user_lookup_table = Pubkey :: from_str ( "YOUR_USER_LOOKUP_TABLE_PUBKEY" ) . unwrap ();
let ix = init_user_metadata (
InitUserMetadataAccounts {
owner ,
fee_payer : owner ,
user_metadata ,
referrer_user_metadata : Some ( referrer_user_metadata ),
},
user_lookup_table ,
);
Once UserMetadata is created with a referrer, the referrer cannot be changed. Always check if UserMetadata exists before attempting to create it.
Send Transaction use solana_sdk :: transaction :: Transaction ;
use solana_sdk :: message :: Message ;
let message = Message :: new ( & [ ix ], Some ( & owner ));
let recent_blockhash = rpc_client . get_latest_blockhash () ? ;
let tx = Transaction :: new ( & [ & signer ], message , recent_blockhash );
let signature = rpc_client . send_and_confirm_transaction ( & tx ) ? ;
println! ( "UserMetadata created with referrer! Signature: {signature}" );
When to Use This vs Deposit with Referral
Use this method when:
You want to link a referrer to a user before they make their first deposit
You’re creating UserMetadata as a separate step from deposit operations
You have a simpler flow that doesn’t require immediate deposit
Use Deposit with Referral when:
You want to combine UserMetadata creation and deposit in a single transaction
The user is ready to deposit immediately
You want to minimize the number of transactions