Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Stake ETH on StakeWise (Ethereum liquid staking). Use when the user wants to stake ETH, unstake ETH, or check staked positions on StakeWise V3 vaults. Suppor...
Stake ETH on StakeWise (Ethereum liquid staking). Use when the user wants to stake ETH, unstake ETH, or check staked positions on StakeWise V3 vaults. Suppor...
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run.
Stake ETH on StakeWise V3 and receive osETH (liquid staking token). Earn staking rewards while keeping your ETH liquid.
Stake ETH โ Receive osETH tokens (handles state updates automatically) Unstake ETH โ Burn osETH for ETH Check staked position โ View vault shares and earned rewards Monitor vault state โ Check if keeper state update is required Query harvest proofs โ Get Merkle proofs from subgraph for deposits
Set these environment variables or edit the scripts: export STAKEWISE_VAULT="0x8A93A876912c9F03F88Bc9114847cf5b63c89f56" export KEEPER="0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5" export PRIVATE_KEY="your_private_key" export MY_ADDRESS="your_address" export RPC_URL="https://ethereum-rpc.publicnode.com"
# Stake 0.1 ETH (auto-handles state updates) node scripts/stake.mjs 0.1 # Check staked position node scripts/position.js # Unstake 0.05 osETH node scripts/unstake.js 0.05 # Check if state update required node scripts/check-state.js
StakeWise V3 uses a keeper-oracle pattern for state updates: User (EOA/UP) โ Vault Contract โ Keeper (Oracle) - Validates and processes rewards โ osETH Token - Liquid staking token
ComponentAddressPurposeVault0x8A93A876912c9F03F88Bc9114847cf5b63c89f56Staking/unstaking logicKeeper0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5Oracle for state updatesosETH TokenDynamic per vaultLiquid staking tokenSubgraphhttps://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prodHarvest proofs and data
Why state updates? StakeWise accumulates rewards off-chain via validators Keeper periodically "harvests" and posts state on-chain Users can only deposit when state is current When is state update required? const vault = new ethers.Contract(vaultAddress, vaultAbi, provider); const needsUpdate = await vault.isStateUpdateRequired(); // true = must update state before depositing
Step 1: Check State User โ vault.isStateUpdateRequired() โ Returns: true (update needed) Step 2: Query Subgraph for Harvest Params User โ POST to StakeWise subgraph โ Returns: rewardsRoot, reward, unlockedMevReward, proof[] Step 3: Update State and Deposit User โ vault.updateStateAndDeposit(harvestParams, receiver, referrer) โ Keeper validates harvest โ Vault mints osETH to receiver โ User receives osETH
import { ethers } from 'ethers'; import fetch from 'node-fetch'; // Setup const provider = new ethers.JsonRpcProvider(process.env.RPC_URL); const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider); // Vault ABI (minimal) const VAULT_ABI = [ 'function isStateUpdateRequired() view returns (bool)', 'function updateStateAndDeposit(tuple(bytes32 rewardsRoot, uint256 reward, uint256 unlockedMevReward, bytes32[] proof) harvestParams, address receiver, address referrer) external payable', 'function deposit(address receiver, address referrer) external payable' ]; const vault = new ethers.Contract( process.env.STAKEWISE_VAULT, VAULT_ABI, wallet ); // Amount to stake const stakeAmount = ethers.parseEther('0.1'); // 0.1 ETH // Step 1: Check if state update required const needsUpdate = await vault.isStateUpdateRequired(); console.log('State update required:', needsUpdate); if (needsUpdate) { // Step 2: Query subgraph for harvest params const subgraphQuery = { query: ` query getHarvestProofs($vault: String!) { harvestProofs( where: { vault: $vault } orderBy: blockNumber orderDirection: desc first: 1 ) { rewardsRoot reward unlockedMevReward proof } } `, variables: { vault: process.env.STAKEWISE_VAULT.toLowerCase() } }; const response = await fetch('https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(subgraphQuery) }); const data = await response.json(); const harvestProof = data.data.harvestProofs[0]; // Step 3: Call updateStateAndDeposit const harvestParams = { rewardsRoot: harvestProof.rewardsRoot, reward: BigInt(harvestProof.reward), unlockedMevReward: BigInt(harvestProof.unlockedMevReward), proof: harvestProof.proof }; const tx = await vault.updateStateAndDeposit( harvestParams, process.env.MY_ADDRESS, // receiver ethers.ZeroAddress, // referrer (optional) { value: stakeAmount } ); const receipt = await tx.wait(); console.log(`Staked ${ethers.formatEther(stakeAmount)} ETH with state update`); console.log(`Transaction: ${receipt.hash}`); } else { // Simple deposit (no state update needed) const tx = await vault.deposit( process.env.MY_ADDRESS, ethers.ZeroAddress, { value: stakeAmount } ); const receipt = await tx.wait(); console.log(`Staked ${ethers.formatEther(stakeAmount)} ETH`); console.log(`Transaction: ${receipt.hash}`); }
const OSETH_ABI = [ 'function balanceOf(address) view returns (uint256)', 'function convertToAssets(uint256 shares) view returns (uint256)' ]; // Get osETH token address from vault const osEthAddress = await vault.osToken(); const osEth = new ethers.Contract(osEthAddress, OSETH_ABI, provider); const osEthBalance = await osEth.balanceOf(process.env.MY_ADDRESS); const underlyingEth = await osEth.convertToAssets(osEthBalance); console.log(`osETH Balance: ${ethers.formatEther(osEthBalance)}`); console.log(`Equivalent ETH: ${ethers.formatEther(underlyingEth)}`);
const VAULT_FULL_ABI = [ 'function redeem(uint256 shares, address receiver, address owner) returns (uint256 assets)', 'function maxRedeem(address owner) view returns (uint256)' ]; const vaultFull = new ethers.Contract( process.env.STAKEWISE_VAULT, VAULT_FULL_ABI, wallet ); // Check max redeemable const maxShares = await vaultFull.maxRedeem(process.env.MY_ADDRESS); console.log(`Max redeemable: ${ethers.formatEther(maxShares)} osETH`); // Redeem shares for ETH const sharesToRedeem = ethers.parseEther('0.05'); const tx = await vaultFull.redeem( sharesToRedeem, process.env.MY_ADDRESS, // receiver process.env.MY_ADDRESS // owner ); const receipt = await tx.wait(); console.log(`Redeemed ${ethers.formatEther(sharesToRedeem)} osETH for ETH`); console.log(`Transaction: ${receipt.hash}`);
const query = { query: ` query { harvestProofs( orderBy: blockNumber orderDirection: desc first: 1 ) { id vault rewardsRoot reward unlockedMevReward proof blockNumber } } ` }; const response = await fetch('https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(query) }); const data = await response.json(); console.log(data.data.harvestProofs[0]);
const query = { query: ` query { vaults(first: 1) { id address totalAssets totalShares apr } } ` };
The keeper hasn't posted recent rewards Query subgraph for latest harvest proof Use updateStateAndDeposit() instead of deposit()
Proof may be outdated Always query subgraph immediately before depositing Proofs are block-specific
Trying to redeem more osETH than you have Check balance: osETH.balanceOf(yourAddress)
Emergency pause may be active Check: vault.paused() Wait for StakeWise team to unpause
APY varies: Based on Ethereum validator rewards, typically 3-5% osETH is rebasing: Balance increases automatically as rewards accrue Keeper dependency: Deposits require valid state (keeper must be active) Gas costs: State updates cost more gas than simple deposits MEV rewards: Part of harvest includes MEV extraction rewards
StakeWise App: https://app.stakewise.io StakeWise Docs: https://docs.stakewise.io Subgraph: https://graphs.stakewise.io/mainnet-a/subgraphs/name/stakewise/prod Vault: 0x8A93A876912c9F03F88Bc9114847cf5b63c89f56 Keeper: 0x6B5815467da09DaA7DC83Db21c9239d98Bb487b5
Writing, remixing, publishing, visual generation, and marketing content production.
Largest current source with strong distribution and engagement signals.