Skip to main content
Deposit to Kamino Earn vaults using Privy embedded wallets. This integration allows users to deposit without managing their own private keys.

Earn Deposit from Privy

1

Import Dependencies

Import the required packages for Privy client, Solana RPC communication, and Kamino SDK operations.
import { PrivyClient } from '@privy-io/node';
import {
  createSolanaRpc,
  address,
  pipe,
  createTransactionMessage,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
  appendTransactionMessageInstructions,
  createNoopSigner,
  getBase64EncodedWireTransaction,
  compileTransaction,
} from '@solana/kit';
import { KaminoVault } from '@kamino-finance/klend-sdk';
import { Decimal } from 'decimal.js';
2

Configure Privy and Initialize Client

Set up your Privy credentials and initialize the Privy client and RPC connection.
const PRIVY_APP_ID = 'put-your-privy-app-id-here';
const PRIVY_APP_SECRET = 'put-your-privy-app-secret-here';
const RPC_ENDPOINT = 'https://api.mainnet-beta.solana.com';
const VAULT_ADDRESS = 'HDsayqAsDWy3QvANGqh2yNraqcD8Fnjgh73Mhb3WRS5E'; // Steakhouse USDC Vault
const AUTH_KEY_ID = 'put-your-auth-key-id-here';
const AUTH_KEY_PRIVATE = 'put-your-auth-key-private-here';
const USER_EMAIL = 'put-your-email-here';

const privy = new PrivyClient({
  appId: PRIVY_APP_ID,
  appSecret: PRIVY_APP_SECRET,
});

const rpc = createSolanaRpc(RPC_ENDPOINT);
Update the configuration values with your Privy app credentials and user details. This example uses the Steakhouse USDC Vault.
3

Create Privy User and Wallet

Create a Privy user account and generate an embedded Solana wallet.
await privy.users().create({
  linked_accounts: [{ type: 'email', address: USER_EMAIL }]
});

const { id: walletId, address: walletAddress } = await privy.wallets().create({
  chain_type: 'solana',
  owner_id: AUTH_KEY_ID
});
Before proceeding, fund the wallet with SOL (for transaction fees) and USDC (for deposit). The wallet cannot submit transactions without sufficient funds.
4

Build Deposit Instructions

Initialize the vault and generate deposit instructions using a noop signer.
const vault = new KaminoVault(rpc, address(VAULT_ADDRESS));
await vault.getState();

const noopSigner = createNoopSigner(address(walletAddress));
const bundle = await vault.depositIxs(noopSigner, new Decimal(1.0));
const instructions = [
  ...(bundle.depositIxs || []),
];

if (!instructions.length) throw new Error('No instructions returned');
A noop signer is used to build instructions without requiring the actual private key. Privy will handle signing later.
5

Build Transaction Message

Fetch the latest blockhash and construct the transaction message.
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();

const depositTransactionMessage = pipe(
  createTransactionMessage({ version: 0 }),
  (tx) => setTransactionMessageFeePayerSigner(noopSigner, tx),
  (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),
  (tx) => appendTransactionMessageInstructions(instructions, tx)
);
6

Sign Transaction with Privy

Compile the transaction, serialize it, and sign using Privy’s wallet API.
const compiledTransaction = compileTransaction(depositTransactionMessage);
const serializedTx = getBase64EncodedWireTransaction(compiledTransaction);

const signResponse = await privy.wallets().solana().signTransaction(walletId, {
  transaction: serializedTx,
  authorization_context: {
    authorization_private_keys: [AUTH_KEY_PRIVATE]
  }
});
Privy handles the signing securely using the embedded wallet. The private key never leaves Privy’s infrastructure.
7

Send Transaction

Submit the signed transaction to the Solana network.
const signature = await rpc.sendTransaction(signResponse.signed_transaction as any, {
  encoding: 'base64',
  skipPreflight: true,
}).send();

console.log('Deposit successful! Signature:', signature);
Your deposit is complete! The user’s funds are now deposited in the Kamino Earn vault using their Privy embedded wallet.