Stake
info
We highly recommend use our SDK, so we could support you better in case of some problems. Also, integration with SDK is much easier & more simple than manually.
Live integration on Mainnet - http://solana.lido.fi/
In this document, we walk through the steps to integrate a web application with the Lido deposit function.
Step 1: Ensure an stSOL recipient account exists
The Deposit instruction requires a recipient address - that will receive stSOL as liquid representation of the deposited SOL. Before we make a deposit from a user's wallet, we need to make sure such a recipient account exists - for the depositor to receive stSOL.
Fetch all accounts for the stSOL mint of the staker
- If at least one such account exists, select the first one and proceed to the next step
- If no such account exists, continue with this section.
If no account exists
- Fetch the associated token account for the payer account
- Add the instruction to create the new associated token account
- Return the associated token account's public key
import { AccountLayout, Token, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token';
const { value: accounts } = await connection.getTokenAccountsByOwner(payer, {
mint: stSolMint,
});
const recipient = accounts[0];
if (recipient) {
recipientStSolAddress = recipient.pubkey;
}
// Creating the associated token account if not already exist
const associatedStSolAccount = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
stSolMint,
payer,
);
transaction.add(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
stSolMint,
associatedStSolAccount,
payer,
payer,
),
);
const recipientStSolAddress = associatedStSolAccount;
Step 2: Create Deposit Instruction
- Create the buffer layout in the format of
{ instruction_code: 1 byte, amount: 8 bytes}
:
import { nu64, struct, u8 } from 'buffer-layout';
const dataLayout = struct([u8('instruction'), nu64('amount')]);
const data = Buffer.alloc(dataLayout.span);
- Encode the deposit data using the buffer layout:
import BN from 'bn.js';
dataLayout.encode(
{
instruction: 1, // code of deposit instruction
amount: new BN(amount),
},
data,
);
- Set all keys for the deposit instruction using the program data we fetch earlier:
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
import {
Keypair,
PublicKey,
StakeProgram,
SystemProgram,
SYSVAR_CLOCK_PUBKEY,
} from '@solana/web3.js';
const bufferArray = [
LIDO_ADDRESS.toBuffer(),
Buffer.from('reserve_account'),
];
const [reserveAccount] = await PublicKey.findProgramAddress(bufferArray, programId);
const bufferArrayMint = [
LIDO_ADDRESS.toBuffer(),
Buffer.from('mint_authority'),
];
const [mintAuthority] = await PublicKey.findProgramAddress(bufferArrayMint, programId);
const keys = [
{ pubkey: LIDO_ADDRESS, isSigner: false, isWritable: true },
{ pubkey: payerAddress, isSigner: true, isWritable: true }, // wallet.publicKey
{ pubkey: recipientStSolAddress, isSigner: false, isWritable: true },
{ pubkey: ST_SOL_MINT, isSigner: false, isWritable: true },
{ pubkey: reserveAccount, isSigner: false, isWritable: true },
{ pubkey: mintAuthority, isSigner: false, isWritable: false },
{ pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
];
- Add the instruction to the transaction:
transaction.add(
new TransactionInstruction({
keys,
programId: PROGRAM_ID,
data,
}),
);
Step 3: Sign and send Transaction
- Create a new transaction with the fee payer as the staker
- Add all the above instructions in the sequence
- If we have created a new stSOL, partially sign the transaction using the
newAccount's keypair
- Sign the transaction
- Send the transaction
// Create new transaction
const transaction = new Transaction({ feePayer: payer });
// Set recent blockhash
const { blockhash } = await connection.getRecentBlockhash();
transaction.recentBlockhash = blockhash;
// Add all the above instructions
const recipient = await ensureTokenAccount(
connection,
transaction,
payer,
stSolMint
);
await depositInstruction(payer, amount, recipient, transaction, config);
// Sign the transaction using the wallet
const signed = wallet.signTransaction(transaction);
// Send the serialized signed transaction to the network
connection.sendRawTransaction(
signed.serialize(),
);