Marinade Native Staking#
Marinade Native lets you stake SOL directly with 100+ validators in a single transaction, without smart contract risk. You retain full custody of your stake accounts while Marinade handles validator selection and rebalancing.
Overview#
| Feature | Description |
|---|---|
| Custody | Non-custodial - you keep withdraw authority |
| Smart Contract | No smart contract risk |
| Validators | 100+ validators via SAM |
| Fees | Zero management fees |
| Unstaking | ~1 epoch (~2 days) |
| PSR Protection | Yes |
Users staking through Marinade Native authorize Marinade to manage delegation while keeping the withdraw authority of their stake accounts. You always retain full control to withdraw your SOL.
How It Works#
graph LR
A[Deposit SOL] --> B[Stake Accounts Created]
B --> C[Marinade Sets Stake Authority]
C --> D[Distributed to 100+ Validators]
D --> E[Earn Rewards Every Epoch]
E --> F[Unstake Anytime]
- You deposit SOL → Stake accounts are created with you as withdraw authority
- Marinade manages delegation → Automatically distributes across top validators
- Rewards accrue → Added to your stake accounts each epoch
- Unstake when ready → Instant (small fee) or delayed (free)
Choose Your Product#
| Product | Strategy | Best For | Validators |
|---|---|---|---|
| Max Yield | Optimizes for highest APY | Maximum returns | All SAM validators |
| Select | Curated high-quality set | Conservative approach | Premium validators only |
| Recipes | Custom strategies | Advanced users | Configurable |
Which should I choose?
- Max Yield - Best for most users who want the highest returns
- Select - Best for users who prefer a more conservative, curated validator set
Configuration#
| Description | Value |
|---|---|
| Marinade Stake authority | stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq |
| Marinade Exit authority | ex9CfkBZZd6Nv9XdnoDmmB45ymbu4arXVk7g5pWnt3N |
| Operator | opNS8ENpEMWdXcJUgJCsJTDp7arTXayoBEeBUg6UezP |
| API endpoint | https://native-staking.marinade.finance |
// pnpm i @marinade.finance/native-staking-sdk '@solana/web3.js
import { Connection } from '@solana/web3.js'
import { NativeStakingConfig, NativeStakingSDK } from '@marinade.finance/native-staking-sdk'
const config = new NativeStakingConfig({
connection: new Connection('https://api.mainnet-beta.solana.com', 'confirmed'),
stakeAuthority: new PublicKey('stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq'),
exitAuthority: new PublicKey('ex9CfkBZZd6Nv9XdnoDmmB45ymbu4arXVk7g5pWnt3N'),
nativeStakingApiUrl: 'https://native-staking.marinade.finance',
beneficiary: new PublicKey('opNS8ENpEMWdXcJUgJCsJTDp7arTXayoBEeBUg6UezP'),
})
const sdk = new NativeStakingSDK(config)
export RPC_URL='https://api.mainnet-beta.solana.com'
export STAKE_AUTHORITY='stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq'
export EXIT_AUTHORITY='ex9CfkBZZd6Nv9XdnoDmmB45ymbu4arXVk7g5pWnt3N'
export BENEFICIARY='opNS8ENpEMWdXcJUgJCsJTDp7arTXayoBEeBUg6UezP'
export NATIVE_STAKING_API='https://native-staking.marinade.finance'
| Description | Value |
|--------------------------|--------------------------------------------------|
| Marinade Stake authority | `stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq` |
| Marinade Exit authority | `ex9CfkBZZd6Nv9XdnoDmmB45ymbu4arXVk7g5pWnt3N` |
| Operator | `opNS8ENpEMWdXcJUgJCsJTDp7arTXayoBEeBUg6UezP` |
| API endpoint | `https://native-staking-dev.marinade.finance` |
// pnpm i @marinade.finance/native-staking-sdk '@solana/web3.js
import { Connection } from '@solana/web3.js'
import { NativeStakingConfig, NativeStakingSDK } from '@marinade.finance/native-staking-sdk'
const config = new NativeStakingConfig({
connection: new Connection('https://api.devnet.solana.com', 'confirmed'),
stakeAuthority: new PublicKey('stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq'),
exitAuthority: new PublicKey('ex9CfkBZZd6Nv9XdnoDmmB45ymbu4arXVk7g5pWnt3N'),
nativeStakingApiUrl: 'https://native-staking-dev.marinade.finance',
beneficiary: new PublicKey('opNS8ENpEMWdXcJUgJCsJTDp7arTXayoBEeBUg6UezP'),
})
const sdk = new NativeStakingSDK(config)
export RPC_URL='https://api.devnet.solana.com'
export STAKE_AUTHORITY='stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq'
export EXIT_AUTHORITY='ex9CfkBZZd6Nv9XdnoDmmB45ymbu4arXVk7g5pWnt3N'
export BENEFICIARY='opNS8ENpEMWdXcJUgJCsJTDp7arTXayoBEeBUg6UezP'
export NATIVE_STAKING_API='https://native-staking-dev.marinade.finance'
| Description | Value |
|---|---|
| Marinade Stake authority | STNi1NHDUi6Hvibvonawgze8fM83PFLeJhuGMEXyGps |
| Marinade Exit authority | EX1Fs34ajye3BTMSjTkMdZ8P4hb99vQFWzmueqhKGpH6 |
| Operator | opiNSvKm1aPkbuSjnZfY5vyJUmaVxuQyTJt6jnNTW1L |
| API endpoint | https://ns-prime.marinade.finance |
// pnpm i @marinade.finance/native-staking-sdk '@solana/web3.js
import { Connection } from '@solana/web3.js'
import { NativeStakingConfig, NativeStakingSDK } from '@marinade.finance/native-staking-sdk'
const config = new NativeStakingConfig({
connection: new Connection('https://api.mainnet-beta.solana.com', 'confirmed'),
stakeAuthority: new PublicKey('STNi1NHDUi6Hvibvonawgze8fM83PFLeJhuGMEXyGps'),
exitAuthority: new PublicKey('EX1Fs34ajye3BTMSjTkMdZ8P4hb99vQFWzmueqhKGpH6'),
nativeStakingApiUrl: 'https://ns-prime.marinade.finance',
beneficiary: new PublicKey('opiNSvKm1aPkbuSjnZfY5vyJUmaVxuQyTJt6jnNTW1L'),
})
const sdk = new NativeStakingSDK(config)
export RPC_URL='https://api.mainnet-beta.solana.com'
export STAKE_AUTHORITY='STNi1NHDUi6Hvibvonawgze8fM83PFLeJhuGMEXyGps'
export EXIT_AUTHORITY='EX1Fs34ajye3BTMSjTkMdZ8P4hb99vQFWzmueqhKGpH6'
export BENEFICIARY='opiNSvKm1aPkbuSjnZfY5vyJUmaVxuQyTJt6jnNTW1L'
export NATIVE_STAKING_API='https://ns-prime.marinade.finance'
| Description | Value |
|---|---|
| Marinade Stake authority | STNi1NHDUi6Hvibvonawgze8fM83PFLeJhuGMEXyGps |
| Marinade Exit authority | EX1Fs34ajye3BTMSjTkMdZ8P4hb99vQFWzmueqhKGpH6 |
| Operator | opiNSvKm1aPkbuSjnZfY5vyJUmaVxuQyTJt6jnNTW1L |
| API endpoint | https://ns-prime-dev.marinade.finance |
// pnpm i @marinade.finance/native-staking-sdk '@solana/web3.js
import { Connection } from '@solana/web3.js'
import { NativeStakingConfig, NativeStakingSDK } from '@marinade.finance/native-staking-sdk' // (1)
const config = new NativeStakingConfig({
connection: new Connection('https://api.devnet.solana.com', 'confirmed'),
stakeAuthority: new PublicKey('STNi1NHDUi6Hvibvonawgze8fM83PFLeJhuGMEXyGps'),
exitAuthority: new PublicKey('EX1Fs34ajye3BTMSjTkMdZ8P4hb99vQFWzmueqhKGpH6'),
nativeStakingApiUrl: 'https://ns-prime-dev.marinade.finance',
beneficiary: new PublicKey('opiNSvKm1aPkbuSjnZfY5vyJUmaVxuQyTJt6jnNTW1L'),
})
const sdk = new NativeStakingSDK(config)
export RPC_URL='https://api.devnet.solana.com'
export STAKE_AUTHORITY='STNi1NHDUi6Hvibvonawgze8fM83PFLeJhuGMEXyGps'
export EXIT_AUTHORITY='EX1Fs34ajye3BTMSjTkMdZ8P4hb99vQFWzmueqhKGpH6'
export BENEFICIARY='opiNSvKm1aPkbuSjnZfY5vyJUmaVxuQyTJt6jnNTW1L'
export NATIVE_STAKING_API='https://ns-prime-dev.marinade.finance'
| Description | Value |
|---|---|
| Marinade Stake authority | stRcP4kVnCNubspkcP3BXEthPfZFEriQBqSczDDwmYH |
| Marinade Exit authority | exRcSuzu5XLZYZ4GgeWYDn9qYwQnBycmyG8zBDJhEgY |
| Operator | opRcXCJNdjujMcekTdRjZ7vibxKbM9nyAgQdXVt8kuR |
| API endpoint | https://ns-recipes.marinade.finance |
// pnpm i @marinade.finance/native-staking-sdk '@solana/web3.js
import { Connection } from '@solana/web3.js'
import { NativeStakingConfig, NativeStakingSDK } from '@marinade.finance/native-staking-sdk'
const config = new NativeStakingConfig({
connection: new Connection('https://api.mainnet-beta.solana.com', 'confirmed'),
stakeAuthority: new PublicKey('stRcP4kVnCNubspkcP3BXEthPfZFEriQBqSczDDwmYH'),
exitAuthority: new PublicKey('exRcSuzu5XLZYZ4GgeWYDn9qYwQnBycmyG8zBDJhEgY'),
nativeStakingApiUrl: 'https://ns-recipes.marinade.finance',
beneficiary: new PublicKey('opRcXCJNdjujMcekTdRjZ7vibxKbM9nyAgQdXVt8kuR'),
})
const sdk = new NativeStakingSDK(config)
export RPC_URL='https://api.mainnet-beta.solana.com'
export STAKE_AUTHORITY='stRcP4kVnCNubspkcP3BXEthPfZFEriQBqSczDDwmYH'
export EXIT_AUTHORITY='exRcSuzu5XLZYZ4GgeWYDn9qYwQnBycmyG8zBDJhEgY'
export BENEFICIARY='opRcXCJNdjujMcekTdRjZ7vibxKbM9nyAgQdXVt8kuR'
export NATIVE_STAKING_API='https://ns-recipes.marinade.finance'
Marinade Stake Authority#
Stake accounts with this stake authority set are actively managed by Marinade. See Marinade operations for further details.
Marinade Exit Authority#
This authority is a part of Marinade's state management. Stake accounts with this stake authority set are marked for de-activation. Once stake accounts are de-activated, the stake accounts are merged and users can withdraw the prepared unstaked balance in a single transaction. See Delayed Unstake for further details.
Start staking#
To start staking using Marinade Native, it is necessary to:
- Create a stake account (ideally initialized state)
- Set stake authority to Marinade
// const config = ...
// const sdk = ...
const { connection } = useConnection() // from @solana/wallet-adapter-react
const { sendTransaction, signTransaction, publicKey } = useWallet() // from @solana/wallet-adapter-react
import BN from 'bn.js'
const amount = new BN('2000000000') // 2 SOL
const { createAuthorizedStake, stakeKeypair } = sdk.buildCreateAuthorizedStakeInstructions(publicKey, amount)
const { blockhash } = await connection.getLatestBlockhash()
const tx = new VersionedTransaction(new TransactionMessage({
payerKey: publicKey,
recentBlockhash: blockhash,
instructions: createAuthorizedStake,
}).compileToV0Message())
tx.sign([stakeKeypair]) // add signature of the stake account
await signTransaction(tx) // add signature of the user
await sendTransaction(tx, connection)
WITHDRAW_AUTHORITY=... # Path to file wallet
WITHDRAW_AUTHORITY_PUBKEY=$(solana-keygen pubkey "$WITHDRAW_AUTHORITY")
SEED=$(openssl rand -hex 16) # Any seed up to 32 characters will do
BLOCKHASH=$(solana block -u "$RPC_URL" --commitment finalized --output json | jq '.blockhash' -r)
solana create-stake-account \
-u "$RPC_URL" \
--commitment finalized \
-k "$WITHDRAW_AUTHORITY" \
--seed "$SEED" \
--blockhash "$BLOCKHASH" \
--stake-authority "$STAKE_AUTHORITY" \
"$WITHDRAW_AUTHORITY" "$AMOUNT"
# Optionally trigger immediate re-balancing without waiting for normal schedule
curl -sfLS "${NATIVE_STAKING_API}/v1/rebalance-hint" \
-X POST \
-H 'Content-type: application/json' \
--data "$(jq --null-input -c --arg user "$WITHDRAW_AUTHORITY_PUBKEY" '{ user: $user }')"
Stop Staking#
There are three ways to unstake from Marinade Native:
Instant Unstake#
Skip the cooldown period by using Marinade's liquidity router:
- Go to app.marinade.finance
- Navigate to Manage → Native Stake
- Select your stake accounts
- Choose Instant Unstake
- Pay a small fee (~0.1-0.3%) and receive SOL immediately
Note
Instant unstake uses liquidity pools, so fees vary based on available liquidity.
Delayed Unstake#
Standard Solana unstaking with no fees:
- Go to app.marinade.finance
- Navigate to Manage → Native Stake
- Select your stake accounts
- Choose Delayed Unstake
- Wait ~1 epoch (~2 days) for deactivation
- Withdraw your SOL
# Prepare stake for revoke (delayed unstake)
WITHDRAW_AUTHORITY=... # Path to file wallet
AMOUNT=10 # Amount in SOL to unstake
WITHDRAW_AUTHORITY_PUBKEY=$(solana-keygen pubkey "$WITHDRAW_AUTHORITY")
BLOCKHASH=$(solana block -u "$RPC_URL" --commitment finalized --output json | jq '.blockhash' -r)
# Create memo with unstake request
MEMO=$(jq --null-input -c --arg user "$WITHDRAW_AUTHORITY_PUBKEY" --arg amount "$AMOUNT" '{
PrepareForRevoke: { user: $user, amount: ((($amount | tonumber) * 1e9) | tostring) }
}')
# Send transfer with memo to signal unstake intent
REVOKE_RESULT=$(solana transfer \
-u "$RPC_URL" \
--commitment finalized \
-k "$WITHDRAW_AUTHORITY" \
--blockhash "$BLOCKHASH" \
--with-memo "$MEMO" \
"$BENEFICIARY" 0.0023)
REVOKE_SIGNATURE=$(echo "$REVOKE_RESULT" | awk '/Signature: / { print $2 }')
# Notify API to process the unstake
curl -sfLS "${NATIVE_STAKING_API}/v1/prepare-for-revoke" \
-X POST \
-H 'Content-type: application/json' \
--data "$(jq --null-input -c \
--arg user "$WITHDRAW_AUTHORITY_PUBKEY" \
--arg amount "$AMOUNT" \
--arg signature "$REVOKE_SIGNATURE" \
'{
signature: $signature,
user: $user,
amount: ((($amount | tonumber) * 1e9) | tostring)
}')"
Manual Unstake#
This is not a recommended way of stopping staking with Marinade - this is a way to be used in case of emergency/apocalyptic-like scenarions when Marinade's UI is not available for whatever reason and you want to withdraw funds back to your wallet.
-
Install Solana CLI using Solana's official documentation.
-
If using a hardware wallet, discover wallet to be used with the CLI:
Tip: If you use multiple derived addresses, try changing the number at the end of the command, so e.g.
solana-keygen pubkey "usb://ledger?key=1"orsolana-keygen pubkey "usb://ledger?key=1/0"Tip: For the device to be discoverable through solana-keygen CLI, the device must not be in use by e.g. browser extension at the same time.
-
Find your stake accounts using:
Example outputStake Pubkey: 4mFGSGdeMZsfnAh58g9PpxFN5KtcqHWQRpZVBgxnFoLH Balance: 1000 SOL Rent Exempt Reserve: 0.00228288 SOL Stake account is undelegated Stake Authority: stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq # (1) Withdraw Authority: YOUR-PUBLIC-KEY-IS-HERE Stake Pubkey: C6kBqxp2tvxvMaXz2FPN1f1iiQJD3R25N8kdM9PnxVXP Balance: 1000.048358174 SOL Rent Exempt Reserve: 0.00228288 SOL Delegated Stake: 1000.046075294 SOL Active Stake: 1000.046075294 SOL Delegated Vote Account Address: 4f9n6atJ9jDXBfTCkk4tJAACq2amnW4rAEZUkg61Zbw7 # (2) Stake Authority: stWirqFCf2Uts1JBL1Jsd3r6VBWhgnpdPxCTe1MFjrq # (3) Withdraw Authority: YOUR-PUBLIC-KEY-IS-HERE- This is Marinade's stake authority
- Validator's public key
- This is Marinade's stake authority
In the example above, there are 2 stake accounts listed:
4mFGSGdeMZsfnAh58g9PpxFN5KtcqHWQRpZVBgxnFoLH- this one is undelegated (could be because of some re-balancing by Marinade)C6kBqxp2tvxvMaXz2FPN1f1iiQJD3R25N8kdM9PnxVXP- this one is delegated
-
The account which is NOT delegated, is NOT activating and is NOT in the de-activation process can be withdrawn using a single command:
Bashsolana withdraw-stake --keypair "usb://ledger?key=0" 4mFGSGdeMZsfnAh58g9PpxFN5KtcqHWQRpZVBgxnFoLH YOUR-PUBLIC-KEY ALLTip:
4mFGSGdeMZsfnAh58g9PpxFN5KtcqHWQRpZVBgxnFoLHis a public key of the stake account, see the example above. You will have to adjust this part of the command after you find your own stake accounts.Tip: Notice the ALL at the end of the command. This can be replaced by a number and you can control how much you are withdrawing.
-
The account which IS activated or activating can be withdrawn in the following steps:
Regain the stake authority, so you can control the delegation state of the account:
Bashsolana stake-authorize --keypair "usb://ledger?key=0" --new-stake-authority YOUR-PUBLIC-KEY-GOES-HERE C6kBqxp2tvxvMaXz2FPN1f1iiQJD3R25N8kdM9PnxVXPTip:
C6kBqxp2tvxvMaXz2FPN1f1iiQJD3R25N8kdM9PnxVXPis a public key of the stake account, see the examples above. You will have to adjust this part of the command after you find your own stake accounts.Now de-activate the account:
Bashsolana deactivate-stake --keypair "usb://ledger?key=0" C6kBqxp2tvxvMaXz2FPN1f1iiQJD3R25N8kdM9PnxVXPSolana has a cool-down period of 1 epoch. So just wait for the end of the current epoch (you can see the progress using
solana epoch-info). Your account will be fully de-activated and you will be able to withdraw as in the example above.
Checking Stake Balances#
You can check the status of your stake accounts using the following shell script:
WITHDRAW_AUTHORITY=... # Path to file wallet
WITHDRAW_AUTHORITY_PUBKEY=$(solana-keygen pubkey "$WITHDRAW_AUTHORITY")
EPOCH=$(solana -u "$RPC_URL" epoch)
echo "Wallet balance: $(solana -u "$RPC_URL" balance "$WITHDRAW_AUTHORITY_PUBKEY")"
# Show stakes managed by Marinade
solana stakes -u "$RPC_URL" --output json --withdraw-authority "$WITHDRAW_AUTHORITY_PUBKEY" | jq -r --arg epoch "$EPOCH" --arg authority "$STAKE_AUTHORITY" '
.[]
| select(.staker == $authority)
| {
stake: .stakePubkey,
delegated: ((.delegatedStake//0) / 1e9),
balance: ((.accountBalance//0) / 1e9),
validator: .delegatedVoteAccountAddress,
status: (if .activationEpoch == null then "initialized"
elif .deactivationEpoch == null then
if .activationEpoch < ($epoch | tonumber) then "active" else "activating" end
else
if .deactivationEpoch < ($epoch | tonumber) then "inactive" else "deactivating" end
end)
}'
Marinade operations#
Once the stake account's stake authority is updated, Marinade then: - Splits the original stake account into smaller stake accounts and delegates them to validators. - Periodically de-activates/delegates/merges/splits accounts in the following epochs to ensure ideal distribution of stake. - Periodically Collects extra balance from stake accounts into a reserve account, so it can be delegated.
This way, users preserve withdraw authority and even in case of black-swan event have absolute control of their stake accounts and can withdraw SOL using the Solana's native Stake Program.
Security Model#
Marinade Native uses a Program Derived Address (PDA) as the stake authority for managed stake accounts. This PDA is owned and controlled by a Solana smart contract, which itself is governed by an on-chain SPL multisig.
The SPL multisig enables decentralized control over the stake authority. Only file wallets permitted by the multisig can sign transactions on behalf of the stake authority. If a security incident occurs, the multisig can update or replace the permitted file wallet, ensuring rapid response and mitigation.
Importantly, the worst-case scenario for a compromised stake authority is that an attacker could undelegate stake from validators. However, since withdraw authority remains with the user, no funds can be lost or withdrawn by the attacker. Users always retain full control over their SOL and can withdraw at any time using Solana's native Stake Program.
Frequently Asked Questions#
Is my SOL safe with Native Staking?
Yes. You retain withdraw authority over your stake accounts at all times. Marinade only has stake authority (controls delegation). Even if Marinade were compromised, the worst case is your stake gets undelegated - your funds cannot be taken.
What's the difference between Native Staking and Liquid Staking?
| Aspect | Native Staking | Liquid Staking |
|---|---|---|
| Receive | Stake accounts | mSOL token |
| DeFi usable | No | Yes |
| Smart contract risk | No | Yes (audited) |
| Custody | Full (you own accounts) | Non-custodial |
How do I see my rewards?
Your rewards are automatically added to your stake account balances each epoch. Check your stake accounts via:
- Marinade UI: Manage → Native Stake
- CLI:
solana stakes --withdraw-authority YOUR_PUBKEY - Solscan or Solana Explorer
Can I use a Ledger hardware wallet?
Yes! Native staking works with Ledger. Connect through Phantom or Solflare, or use the Solana CLI directly. See the Manual Unstake section for CLI examples.
What happens if a validator I'm staked to performs poorly?
PSR (Protected Staking Rewards) compensates you from the validator's bond if they underperform. Additionally, Marinade automatically rebalances stake away from poorly performing validators.
How many stake accounts will I have?
Marinade creates multiple stake accounts to distribute your SOL across validators. The exact number depends on your stake amount and Marinade's rebalancing strategy.
Next Steps#
| Action | Link |
|---|---|
| Compare with Liquid Staking | Liquid Staking |
| Understand rewards | Rewards Guide |
| Learn about PSR | Protected Staking Rewards |
| Stake now | app.marinade.finance |