diff --git a/src/chain-observers/classifiers/account-classifier.ts b/src/chain-observers/classifiers/account-classifier.ts
index 17d14c3cfe606f418d862b0c6b0de147db9574b3..81e5a5480ea4fa9e1cc746dcc6f4b43b894ec66a 100644
--- a/src/chain-observers/classifiers/account-classifier.ts
+++ b/src/chain-observers/classifiers/account-classifier.ts
@@ -29,6 +29,8 @@ export interface IAccount {
   postingJsonMetadata: Record<string, any>;
   jsonMetadata: Record<string, any>;
   balance: IAccountBalance;
+  recoveryAccount: string;
+  governanceVoteExpiration?: Date;
 }
 
 export interface IAccountData {
diff --git a/src/chain-observers/classifiers/change-recovery-in-progress-classifier.ts b/src/chain-observers/classifiers/change-recovery-in-progress-classifier.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7fd32cc5b1d047fc6097019afe42c8260d3a7304
--- /dev/null
+++ b/src/chain-observers/classifiers/change-recovery-in-progress-classifier.ts
@@ -0,0 +1,15 @@
+import { CollectorClassifierBase } from "./collector-classifier-base";
+
+export interface IAccountChangingRecovery {
+  accountToRecover: string;
+  recoveryAccount: string;
+  effectiveOn: Date;
+}
+
+export interface IChangeRecoveryInProgressData {
+  recoveringAccounts: Record<string, IAccountChangingRecovery>;
+}
+
+export class ChangeRecoveryInProgressClassifier extends CollectorClassifierBase {
+  public type!: IChangeRecoveryInProgressData;
+}
diff --git a/src/chain-observers/classifiers/decline-voting-rights-classifier.ts b/src/chain-observers/classifiers/decline-voting-rights-classifier.ts
new file mode 100644
index 0000000000000000000000000000000000000000..60d33eba197780c1e235053046cc31fbe8ae799f
--- /dev/null
+++ b/src/chain-observers/classifiers/decline-voting-rights-classifier.ts
@@ -0,0 +1,14 @@
+import { CollectorClassifierBase } from "./collector-classifier-base";
+
+export interface IDeclinedVotingRightsAccount {
+  account: string;
+  effectiveDate: Date;
+}
+
+export interface IDeclineVotingRightsAccountsData {
+  declineVotingRightsAccounts: Record<string, IDeclinedVotingRightsAccount>;
+}
+
+export class DeclineVotingRightsClassifier extends CollectorClassifierBase {
+  public type!: IDeclineVotingRightsAccountsData;
+}
diff --git a/src/chain-observers/classifiers/index.ts b/src/chain-observers/classifiers/index.ts
index 0301e7ecf2ba640e3ded8bf82fbd88cfc9e93d92..26a340e13236e16726f7904458798649c78922a3 100644
--- a/src/chain-observers/classifiers/index.ts
+++ b/src/chain-observers/classifiers/index.ts
@@ -7,3 +7,5 @@ export { ImpactedAccountClassifier } from "./impacted-account-classifier";
 export { OperationClassifier } from "./operation-classifier";
 export { FeedPriceClassifier } from "./feed-price-classifier";
 export { WitnessClassifier } from "./witness-classifier";
+export { ChangeRecoveryInProgressClassifier } from "./change-recovery-in-progress-classifier";
+export { DeclineVotingRightsClassifier } from "./decline-voting-rights-classifier";
diff --git a/src/chain-observers/collectors/jsonrpc/account-collector.ts b/src/chain-observers/collectors/jsonrpc/account-collector.ts
index 316d98c30296e309cf79e7552b0156552b4a50f2..f6ed8e14731c9b603fde997d7bfed15e80641222 100644
--- a/src/chain-observers/collectors/jsonrpc/account-collector.ts
+++ b/src/chain-observers/collectors/jsonrpc/account-collector.ts
@@ -39,9 +39,16 @@ export class AccountCollector extends CollectorBase {
 
       const { accounts: apiAccounts } = await this.worker.chain!.api.database_api.find_accounts({ accounts: chunk });
 
-      for(const account of apiAccounts)
+      for(const account of apiAccounts) {
+        let governanceVoteExpiration: Date | undefined = new Date(`${account.governance_vote_expiration_ts}Z`);
+
+        if (governanceVoteExpiration.getTime() <= 0) // Null time
+          governanceVoteExpiration = undefined;
+
         accounts[account.name] = {
           name: account.name,
+          recoveryAccount: account.recovery_account,
+          governanceVoteExpiration,
           postingJsonMetadata: tryParseJson(account.posting_json_metadata),
           jsonMetadata: tryParseJson(account.json_metadata),
           balance: {
@@ -89,6 +96,7 @@ export class AccountCollector extends CollectorBase {
             }
           }
         };
+      }
     }
 
     return {
diff --git a/src/chain-observers/collectors/jsonrpc/change-recovery-in-progress-collector.ts b/src/chain-observers/collectors/jsonrpc/change-recovery-in-progress-collector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9b4874f5b0d5971b7318750c5e91065e87adb0d2
--- /dev/null
+++ b/src/chain-observers/collectors/jsonrpc/change-recovery-in-progress-collector.ts
@@ -0,0 +1,48 @@
+import { IAccountChangingRecovery } from "../../classifiers/change-recovery-in-progress-classifier";
+import { DataEvaluationContext } from "../../factories/data-evaluation-context";
+import { CollectorBase, TAvailableClassifiers } from "../collector-base";
+
+export interface IChangeRecoveryCollectorOptions {
+  changeRecoveryAccount: string;
+}
+
+const MAX_CHANGE_RECOVERY_GET_LIMIT = 100;
+
+export class ChangeRecoveryInProgressCollector extends CollectorBase {
+  private readonly changeRecoveryAccounts: Record<string, number> = {};
+
+  protected pushOptions(data: IChangeRecoveryCollectorOptions): void {
+    this.changeRecoveryAccounts[data.changeRecoveryAccount] = (this.changeRecoveryAccounts[data.changeRecoveryAccount] || 0) + 1;
+  }
+
+  protected popOptions(data: IChangeRecoveryCollectorOptions): void {
+    this.changeRecoveryAccounts[data.changeRecoveryAccount] = (this.changeRecoveryAccounts[data.changeRecoveryAccount] || 1) - 1;
+
+    if (this.changeRecoveryAccounts[data.changeRecoveryAccount] === 0)
+      delete this.changeRecoveryAccounts[data.changeRecoveryAccount];
+  }
+
+  public async fetchData(_: DataEvaluationContext) {
+    const retrieveChangeRecoveryAccounts: Record<string, IAccountChangingRecovery> = {};
+
+    const recoveryAccounts = Object.keys(this.changeRecoveryAccounts);
+    for (let i = 0; i < recoveryAccounts.length; i += MAX_CHANGE_RECOVERY_GET_LIMIT) {
+      const chunk = recoveryAccounts.slice(i, i + MAX_CHANGE_RECOVERY_GET_LIMIT);
+
+      const { requests } = await this.worker.chain!.api.database_api.find_change_recovery_account_requests({ accounts: chunk });
+
+      for(const request of requests)
+        retrieveChangeRecoveryAccounts[request.account_to_recover] = {
+          accountToRecover: request.account_to_recover,
+          recoveryAccount: request.recovery_account,
+          effectiveOn: new Date(`${request.effective_on}Z`)
+        };
+    }
+
+    return {
+      ChangeRecoveryInProgressClassifier: {
+        recoveringAccounts: retrieveChangeRecoveryAccounts
+      }
+    } satisfies Partial<TAvailableClassifiers>;
+  };
+}
diff --git a/src/chain-observers/collectors/jsonrpc/decline-voting-rights-collector.ts b/src/chain-observers/collectors/jsonrpc/decline-voting-rights-collector.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9720b88ab274b29ed2c2969147435bf8ea3b05f0
--- /dev/null
+++ b/src/chain-observers/collectors/jsonrpc/decline-voting-rights-collector.ts
@@ -0,0 +1,47 @@
+import { IDeclinedVotingRightsAccount } from "../../classifiers/decline-voting-rights-classifier";
+import { DataEvaluationContext } from "../../factories/data-evaluation-context";
+import { CollectorBase, TAvailableClassifiers } from "../collector-base";
+
+export interface IDeclineVotingRightsCollectorOptions {
+  declineVotingRightsAccount: string;
+}
+
+const MAX_DECLINED_VOTING_RIGHTS_GET_LIMIT = 100;
+
+export class DeclineVotingRightsCollector extends CollectorBase {
+  private readonly declineVotingRightsAccounts: Record<string, number> = {};
+
+  protected pushOptions(data: IDeclineVotingRightsCollectorOptions): void {
+    this.declineVotingRightsAccounts[data.declineVotingRightsAccount] = (this.declineVotingRightsAccounts[data.declineVotingRightsAccount] || 0) + 1;
+  }
+
+  protected popOptions(data: IDeclineVotingRightsCollectorOptions): void {
+    this.declineVotingRightsAccounts[data.declineVotingRightsAccount] = (this.declineVotingRightsAccounts[data.declineVotingRightsAccount] || 1) - 1;
+
+    if (this.declineVotingRightsAccounts[data.declineVotingRightsAccount] === 0)
+      delete this.declineVotingRightsAccounts[data.declineVotingRightsAccount];
+  }
+
+  public async fetchData(_: DataEvaluationContext) {
+    const declineVotingRightsAccounts: Record<string, IDeclinedVotingRightsAccount> = {};
+
+    const recoveryAccounts = Object.keys(this.declineVotingRightsAccounts);
+    for (let i = 0; i < recoveryAccounts.length; i += MAX_DECLINED_VOTING_RIGHTS_GET_LIMIT) {
+      const chunk = recoveryAccounts.slice(i, i + MAX_DECLINED_VOTING_RIGHTS_GET_LIMIT);
+
+      const { requests } = await this.worker.chain!.api.database_api.find_decline_voting_rights_requests({ accounts: chunk });
+
+      for(const request of requests)
+        declineVotingRightsAccounts[request.account] = {
+          account: request.account,
+          effectiveDate: new Date(`${request.effective_date}Z`)
+        };
+    }
+
+    return {
+      DeclineVotingRightsClassifier: {
+        declineVotingRightsAccounts
+      }
+    } satisfies Partial<TAvailableClassifiers>;
+  };
+}
diff --git a/src/chain-observers/collectors/jsonrpc/witness-collector.ts b/src/chain-observers/collectors/jsonrpc/witness-collector.ts
index 39f34098dd19108d50ea23c8e598e9137f8a0ea6..f1b50ef41018e431ea400845ac13588b847480ce 100644
--- a/src/chain-observers/collectors/jsonrpc/witness-collector.ts
+++ b/src/chain-observers/collectors/jsonrpc/witness-collector.ts
@@ -32,8 +32,8 @@ export class WitnessCollector extends CollectorBase {
       const { witnesses: owners } = await this.worker.chain!.api.database_api.find_witnesses({ owners: chunk });
 
       for(const account of owners)
-        witnessNames[account.owner] = {
-          name: account.owner,
+        witnesses[account.owner] = {
+          owner: account.owner,
           runningVersion: account.running_version,
           totalMissedBlocks: account.total_missed,
           lastConfirmedBlockNum: account.last_confirmed_block_num
diff --git a/src/chain-observers/factories/jsonrpc/factory-data.ts b/src/chain-observers/factories/jsonrpc/factory-data.ts
index 3662dfb460c0d1575122976ea5e4024a72d06435..1b5bf654860cf38cb588a30ef27ba7137bfc96c6 100644
--- a/src/chain-observers/factories/jsonrpc/factory-data.ts
+++ b/src/chain-observers/factories/jsonrpc/factory-data.ts
@@ -1,6 +1,8 @@
 import type { WorkerBee } from "../../../bot";
 import {
   AccountClassifier, BlockClassifier, BlockHeaderClassifier,
+  ChangeRecoveryInProgressClassifier,
+  DeclineVotingRightsClassifier,
   DynamicGlobalPropertiesClassifier, FeedPriceClassifier, ImpactedAccountClassifier, OperationClassifier, RcAccountClassifier,
   WitnessClassifier
 } from "../../classifiers";
@@ -11,6 +13,8 @@ import { ImpactedAccountCollector } from "../../collectors/common/impacted-accou
 import { OperationCollector } from "../../collectors/common/operation-collector";
 import { AccountCollector } from "../../collectors/jsonrpc/account-collector";
 import { BlockCollector } from "../../collectors/jsonrpc/block-collector";
+import { ChangeRecoveryInProgressCollector } from "../../collectors/jsonrpc/change-recovery-in-progress-collector";
+import { DeclineVotingRightsCollector } from "../../collectors/jsonrpc/decline-voting-rights-collector";
 import { DynamicGlobalPropertiesCollector } from "../../collectors/jsonrpc/dynamic-global-properties-collector";
 import { FeedPriceCollector } from "../../collectors/jsonrpc/feed-price-collector";
 import { RcAccountCollector } from "../../collectors/jsonrpc/rc-account-collector";
@@ -25,5 +29,7 @@ export const JsonRpcFactoryData: (worker: WorkerBee) => Array<[IEvaluationContex
   [ImpactedAccountClassifier, new ImpactedAccountCollector(worker)],
   [OperationClassifier, new OperationCollector(worker)],
   [FeedPriceClassifier, new FeedPriceCollector(worker)],
-  [WitnessClassifier, new WitnessCollector(worker)]
+  [WitnessClassifier, new WitnessCollector(worker)],
+  [ChangeRecoveryInProgressClassifier, new ChangeRecoveryInProgressCollector(worker)],
+  [DeclineVotingRightsClassifier, new DeclineVotingRightsCollector(worker)]
 ]);
diff --git a/src/chain-observers/filters/alarm-filter.ts b/src/chain-observers/filters/alarm-filter.ts
new file mode 100644
index 0000000000000000000000000000000000000000..19efd4db7501b5f83d55bbd6e52be6497de727fa
--- /dev/null
+++ b/src/chain-observers/filters/alarm-filter.ts
@@ -0,0 +1,50 @@
+import type { WorkerBee } from "../../bot";
+import { AccountClassifier, ChangeRecoveryInProgressClassifier, DeclineVotingRightsClassifier } from "../classifiers";
+import type { TRegisterEvaluationContext } from "../classifiers/collector-classifier-base";
+import type { DataEvaluationContext } from "../factories/data-evaluation-context";
+import { FilterBase } from "./filter-base";
+
+export const STEEM_ACCOUNT_NAME = "steem";
+export const ONE_MONTH_MS = 1000 * 60 * 60 * 24 * 31;
+
+export class AlarmFilter extends FilterBase {
+  public constructor(
+    worker: WorkerBee,
+    private readonly account: string
+  ) {
+    super(worker);
+  }
+
+  public usedContexts(): Array<TRegisterEvaluationContext> {
+    return [
+      AccountClassifier.forOptions({ account: this.account }),
+      ChangeRecoveryInProgressClassifier.forOptions({ changeRecoveryAccount: this.account }),
+      DeclineVotingRightsClassifier.forOptions({ declineVotingRightsAccount: this.account })
+    ];
+  }
+
+  public async match(data: DataEvaluationContext): Promise<boolean> {
+    const { accounts } = await data.get(AccountClassifier);
+
+    if (accounts[this.account].recoveryAccount === STEEM_ACCOUNT_NAME)
+      return true;
+
+    if (accounts[this.account].governanceVoteExpiration === undefined)
+      return true;
+
+    if (accounts[this.account].governanceVoteExpiration!.getTime() < (Date.now() + ONE_MONTH_MS))
+      return true;
+
+    const { recoveringAccounts } = await data.get(ChangeRecoveryInProgressClassifier);
+
+    if (recoveringAccounts[this.account])
+      return true;
+
+    const { declineVotingRightsAccounts } = await data.get(DeclineVotingRightsClassifier);
+
+    if (declineVotingRightsAccounts[this.account])
+      return true;
+
+    return false;
+  }
+}
diff --git a/src/chain-observers/providers/alarm-provider.ts b/src/chain-observers/providers/alarm-provider.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ecb6a8f57be126a5bc40e4632e2c7c552929d4f2
--- /dev/null
+++ b/src/chain-observers/providers/alarm-provider.ts
@@ -0,0 +1,80 @@
+import { TAccountName } from "@hiveio/wax";
+import { AccountClassifier, ChangeRecoveryInProgressClassifier, DeclineVotingRightsClassifier } from "../classifiers";
+import { TRegisterEvaluationContext } from "../classifiers/collector-classifier-base";
+import { DataEvaluationContext } from "../factories/data-evaluation-context";
+import { ONE_MONTH_MS, STEEM_ACCOUNT_NAME } from "../filters/alarm-filter";
+import { ProviderBase } from "./provider-base";
+
+export enum EAlarmType {
+  LEGACY_RECOVERY_ACCOUNT_SET,
+  GOVERNANCE_VOTE_EXPIRATION_SOON,
+  GOVERNANCE_VOTE_EXPIRED,
+  RECOVERY_ACCOUNT_IS_CHANGING,
+  DECLINING_VOTING_RIGHTS
+}
+
+export type TAlarmAccounts<TAccounts extends Array<TAccountName>> = {
+  [K in TAccounts[number]]: EAlarmType[];
+};
+
+export interface IAlarmAccountsData<TAccounts extends Array<TAccountName>> {
+  alarmsPerAccount: TAlarmAccounts<TAccounts>;
+};
+
+export class AlarmProvider<TAccounts extends Array<TAccountName> = Array<TAccountName>> extends ProviderBase {
+  public constructor(
+    private readonly accounts: TAccounts
+  ) {
+    super();
+  }
+
+  public usedContexts(): Array<TRegisterEvaluationContext> {
+    return [
+      ...this.accounts.map(account => AccountClassifier.forOptions({
+        account
+      })),
+      ...this.accounts.map(account => ChangeRecoveryInProgressClassifier.forOptions({
+        changeRecoveryAccount: account
+      })),
+      ...this.accounts.map(account => DeclineVotingRightsClassifier.forOptions({
+        declineVotingRightsAccount: account
+      }))
+    ];
+  }
+
+  public async provide(data: DataEvaluationContext): Promise<IAlarmAccountsData<TAccounts>> {
+    const result: IAlarmAccountsData<TAccounts> = {
+      alarmsPerAccount: this.accounts.reduce((prev, curr) => {
+        prev[curr]  = [];
+
+        return prev;
+      }, {} as TAlarmAccounts<TAccounts>)
+    };
+
+    const { accounts } = await data.get(AccountClassifier);
+    for(const account of this.accounts) {
+      if (accounts[account].recoveryAccount === STEEM_ACCOUNT_NAME)
+        result.alarmsPerAccount[account].push(EAlarmType.LEGACY_RECOVERY_ACCOUNT_SET);
+      if (accounts[account].governanceVoteExpiration === undefined)
+        result.alarmsPerAccount[account].push(EAlarmType.GOVERNANCE_VOTE_EXPIRED);
+      if (accounts[account].governanceVoteExpiration!.getTime() < (Date.now() + ONE_MONTH_MS))
+        result.alarmsPerAccount[account].push(EAlarmType.GOVERNANCE_VOTE_EXPIRATION_SOON);
+    }
+
+    const { recoveringAccounts } = await data.get(ChangeRecoveryInProgressClassifier);
+
+    for(const account of this.accounts)
+      if (recoveringAccounts[account])
+        result.alarmsPerAccount[account].push(EAlarmType.RECOVERY_ACCOUNT_IS_CHANGING);
+
+
+    const { declineVotingRightsAccounts } = await data.get(DeclineVotingRightsClassifier);
+
+    for(const account of this.accounts)
+      if (declineVotingRightsAccounts[account])
+        result.alarmsPerAccount[account].push(EAlarmType.DECLINING_VOTING_RIGHTS);
+
+
+    return result;
+  }
+}
diff --git a/src/queen.ts b/src/queen.ts
index 7b1c8dcffebf6c20aed4f3629fa3aae06e011c5b..b6dabb1b0875f3fedde79f22ff6f67ebf7aa996d 100644
--- a/src/queen.ts
+++ b/src/queen.ts
@@ -4,6 +4,7 @@ import { WorkerBee } from "./bot";
 import { AccountCreatedFilter } from "./chain-observers/filters/account-created-filter";
 import { AccountFullManabarFilter } from "./chain-observers/filters/account-full-manabar-filter";
 import { AccountMetadataChangeFilter } from "./chain-observers/filters/account-metadata-change-filter";
+import { AlarmFilter } from "./chain-observers/filters/alarm-filter";
 import { BalanceChangeFilter } from "./chain-observers/filters/balance-change-filter";
 import { BlockNumberFilter } from "./chain-observers/filters/block-filter";
 import { LogicalAndFilter, LogicalOrFilter } from "./chain-observers/filters/composite-filter";
@@ -24,6 +25,7 @@ import { VoteFilter } from "./chain-observers/filters/vote-filter";
 import { WhaleAlertFilter } from "./chain-observers/filters/whale-alert-filter";
 import { WitnessMissedBlocksFilter } from "./chain-observers/filters/witness-miss-block-filter";
 import { AccountProvider } from "./chain-observers/providers/account-provider";
+import { AlarmProvider } from "./chain-observers/providers/alarm-provider";
 import { BlockHeaderProvider } from "./chain-observers/providers/block-header-provider";
 import { BlockProvider } from "./chain-observers/providers/block-provider";
 import { ExchangeTransferProvider } from "./chain-observers/providers/exchange-transfer-provider";
@@ -180,6 +182,15 @@ export class QueenBee<TPreviousSubscriberData extends object = {}> {
     return this;
   }
 
+  public onAlarm<
+    TAccount extends TAccountName
+  >(watchAccount: TAccount): QueenBee<TPreviousSubscriberData & Awaited<ReturnType<AlarmProvider<[TAccount]>["provide"]>>> {
+    this.operands.push(new AlarmFilter(this.worker, watchAccount));
+    this.providers.push(new AlarmProvider<[TAccount]>([watchAccount]));
+
+    return this;
+  }
+
   public onImpactedAccount(account: TAccountName): QueenBee<TPreviousSubscriberData> {
     this.operands.push(new ImpactedAccountFilter(this.worker, account));
 
diff --git a/src/wax/index.ts b/src/wax/index.ts
index d886a225307e60d9bc635f8ce45f7410426fcbe6..795b6a731dd391a933f138899d1449b7ed85e7c0 100644
--- a/src/wax/index.ts
+++ b/src/wax/index.ts
@@ -22,6 +22,21 @@ export type WaxExtendTypes = {
         // ...
       }>; };
     };
+    find_decline_voting_rights_requests: {
+      params: { accounts: string[]; };
+      result: { requests: Array<{
+        account: string;
+        effective_date: string;
+      }>; };
+    };
+    find_change_recovery_account_requests: {
+      params: { accounts: string[]; };
+      result: { requests: Array<{
+        account_to_recover: string;
+        recovery_account: string;
+        effective_on: string;
+      }>; };
+    };
   }
 };