Параметры
Открытый ключ стейкинг-счёта (в кодировке base-58)
Объект конфигурации, содержащий:Уровень подтверждения (processed, confirmed, finalized)
Эпоха, для которой нужно рассчитать активацию стейка
Ответ
Объект, содержащий:Состояние активации (active, inactive, activating, deactivating)
Размер активного стейка в lamports
Размер неактивного стейка в lamports
Примеры кода
Базовый запрос
curl https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY -X POST -H "Content-Type: application/json" -d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getStakeActivation",
"params": [
"4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLZj"
]
}'
Использование web3.js
import { Connection, PublicKey } from '@solana/web3.js';
const connection = new Connection('https://fra.rpc.orbitflare.com?api_key=YOUR-API-KEY');
// Get stake activation
const stakeAccount = new PublicKey('4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLZj');
const activation = await connection.getStakeActivation(stakeAccount);
console.log('Stake activation:', activation);
// Get stake activation with analysis
async function getStakeActivationWithAnalysis(
stakeAccount: PublicKey,
config?: { commitment?: string; epoch?: number }
) {
const activation = await connection.getStakeActivation(stakeAccount, config);
return {
activation,
analysis: {
totalStake: activation.active + activation.inactive,
activePercentage: (activation.active / (activation.active + activation.inactive)) * 100,
state: activation.state,
metadata: {
timestamp: Date.now(),
epoch: config?.epoch,
commitment: config?.commitment
}
}
};
}
Примечания
- Возвращает информацию об активации стейкинга для заданного стейкинг-счёта
- Состояние активации указывает, активен ли стейк, неактивен, активируется или деактивируется
- Ответ приходит немедленно, так как читается из текущего состояния
- Активация стейка может изменяться в зависимости от эпохи и уровня подтверждения
- Стейкинг-счёт должен быть действительным
Рекомендации
- Используйте подходящий уровень подтверждения в зависимости от ваших потребностей
- Кэшируйте результаты там, где это уместно, для снижения нагрузки на RPC
- Отслеживайте изменения в активации стейка
- Рассмотрите использование подписки на websocket для обновлений в реальном времени
- Обрабатывайте сетевые ошибки и выполняйте повторные попытки при необходимости
Распространённые ошибки
| Код | Сообщение | Решение |
|---|
| -32601 | Method not found | Убедитесь, что вы подключены к узлу Solana RPC |
| -32602 | Invalid params | Проверьте открытый ключ стейкинг-счёта |
| -32007 | Stake account not found | Убедитесь, что стейкинг-счёт существует |
| -32008 | Invalid stake account | Убедитесь, что счёт является действительным стейкинг-счётом |
Сценарии использования
-
Анализ активации стейка
interface StakeActivationAnalysis {
account: string;
activation: {
state: string;
active: number;
inactive: number;
};
metrics: {
totalStake: number;
activePercentage: number;
activationProgress?: number;
deactivationProgress?: number;
};
metadata: {
timestamp: number;
epoch?: number;
commitment?: string;
};
}
class StakeActivationAnalyzer {
async analyzeStakeActivation(
stakeAccount: PublicKey,
config?: { commitment?: string; epoch?: number }
): Promise<StakeActivationAnalysis> {
const activation = await connection.getStakeActivation(stakeAccount, config);
const metrics = {
totalStake: activation.active + activation.inactive,
activePercentage: (activation.active / (activation.active + activation.inactive)) * 100
};
if (activation.state === 'activating' || activation.state === 'deactivating') {
const progress = (activation.active / (activation.active + activation.inactive)) * 100;
if (activation.state === 'activating') {
metrics.activationProgress = progress;
} else {
metrics.deactivationProgress = progress;
}
}
return {
account: stakeAccount.toBase58(),
activation,
metrics,
metadata: {
timestamp: Date.now(),
epoch: config?.epoch,
commitment: config?.commitment
}
};
}
}
-
Мониторинг активации стейка
interface StakeActivationChange {
account: string;
previousState: string;
currentState: string;
activeChange: number;
inactiveChange: number;
metadata: {
timestamp: number;
epoch?: number;
};
}
class StakeActivationMonitor {
private previousStates: Map<string, { state: string; active: number; inactive: number }> = new Map();
async monitorStakeActivation(
stakeAccount: PublicKey,
config?: { commitment?: string; epoch?: number }
): Promise<StakeActivationChange | null> {
const activation = await connection.getStakeActivation(stakeAccount, config);
const accountKey = stakeAccount.toBase58();
const previous = this.previousStates.get(accountKey);
if (!previous) {
this.previousStates.set(accountKey, {
state: activation.state,
active: activation.active,
inactive: activation.inactive
});
return null;
}
if (previous.state !== activation.state ||
previous.active !== activation.active ||
previous.inactive !== activation.inactive) {
const change: StakeActivationChange = {
account: accountKey,
previousState: previous.state,
currentState: activation.state,
activeChange: activation.active - previous.active,
inactiveChange: activation.inactive - previous.inactive,
metadata: {
timestamp: Date.now(),
epoch: config?.epoch
}
};
this.previousStates.set(accountKey, {
state: activation.state,
active: activation.active,
inactive: activation.inactive
});
return change;
}
return null;
}
}
-
Планирование активации стейка
interface StakeActivationPlan {
account: string;
currentState: string;
targetState: string;
steps: Array<{
action: string;
estimatedTime: number;
requiredStake: number;
}>;
metadata: {
timestamp: number;
currentEpoch: number;
};
}
class StakeActivationPlanner {
private readonly slotsPerEpoch = 432000; // Solana's slots per epoch
private readonly slotsPerSecond = 2; // Solana's target slot rate
async planStakeActivation(
stakeAccount: PublicKey,
targetState: string
): Promise<StakeActivationPlan> {
const [activation, currentEpoch] = await Promise.all([
connection.getStakeActivation(stakeAccount),
connection.getEpochInfo()
]);
const steps: Array<{
action: string;
estimatedTime: number;
requiredStake: number;
}> = [];
if (activation.state !== targetState) {
if (targetState === 'active' && activation.state === 'inactive') {
steps.push({
action: 'activate',
estimatedTime: (this.slotsPerEpoch / this.slotsPerSecond) / 2, // Half an epoch
requiredStake: activation.active + activation.inactive
});
} else if (targetState === 'inactive' && activation.state === 'active') {
steps.push({
action: 'deactivate',
estimatedTime: (this.slotsPerEpoch / this.slotsPerSecond) / 2, // Half an epoch
requiredStake: activation.active + activation.inactive
});
}
}
return {
account: stakeAccount.toBase58(),
currentState: activation.state,
targetState,
steps,
metadata: {
timestamp: Date.now(),
currentEpoch: currentEpoch.epoch
}
};
}
}