Claude-skill-registry 1k-adding-socket-events

Adds new WebSocket event subscriptions to OneKey. Use when implementing new socket events, handling server push messages, or adding real-time data subscriptions. Socket, WebSocket, event, subscription, push, real-time.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/1k-adding-socket-events" ~/.claude/skills/majiayu000-claude-skill-registry-1k-adding-socket-events && rm -rf "$T"
manifest: skills/data/1k-adding-socket-events/SKILL.md
source content

Adding WebSocket Event Subscriptions

This skill documents how to add new WebSocket event subscriptions in the OneKey app.

Overview

WebSocket events enable real-time server-to-client communication. The pattern involves:

  1. Define the event name in
    EAppSocketEventNames
    enum
  2. Define the payload type interface
  3. Add the event handler in
    PushProviderWebSocket

Key Files

PurposeLocation
Event names & payload types
packages/shared/types/socket.ts
WebSocket event handlers
packages/kit-bg/src/services/ServiceNotification/PushProvider/PushProviderWebSocket.ts

Step-by-Step Guide

Step 1: Define Event Name

Add the new event name to

EAppSocketEventNames
in
packages/shared/types/socket.ts
:

export enum EAppSocketEventNames {
  notification = 'notification',
  ping = 'ping',
  pong = 'pong',
  ack = 'ack',
  market = 'market',
  primeConfigChanged = 'CONFIG_CHANGE',
  // ... existing events
  myNewEvent = 'MY_NEW_EVENT',  // Add your new event
}

Convention: Use camelCase for the enum key, SCREAMING_SNAKE_CASE for the string value.

Step 2: Define Payload Type

Add the payload interface in

packages/shared/types/socket.ts
:

export interface IMyNewEventPayload {
  msgId: string;  // Required for acknowledgment
  // Add other fields as needed
  someData?: string;
  someNumber?: number;
}

Important: Always include

msgId: string
for message acknowledgment.

Step 3: Add Event Handler

In

packages/kit-bg/src/services/ServiceNotification/PushProvider/PushProviderWebSocket.ts
:

  1. Import the new payload type:
import type {
  // ... existing imports
  IMyNewEventPayload,
} from '@onekeyhq/shared/types/socket';
  1. Add the event handler in
    initWebSocket()
    method:
this.socket.on(EAppSocketEventNames.myNewEvent, (payload: IMyNewEventPayload) => {
  // 1. Acknowledge receipt (required for most events)
  void this.backgroundApi.serviceNotification.ackNotificationMessage({
    msgId: payload.msgId,
    action: ENotificationPushMessageAckAction.arrived,
  });

  // 2. Handle the event (call appropriate service method)
  void this.backgroundApi.someService.handleMyNewEvent(payload);
});

Complete Example: userInfoUpdated Event

Here's a real example from the codebase:

1. Event Name (socket.ts)

export enum EAppSocketEventNames {
  // ... other events
  userInfoUpdated = 'USER_INFO_UPDATED',
}

2. Payload Type (socket.ts)

export interface IUserInfoUpdatedPayload {
  msgId: string;
}

3. Event Handler (PushProviderWebSocket.ts)

this.socket.on(EAppSocketEventNames.userInfoUpdated, (payload: IUserInfoUpdatedPayload) => {
  void this.backgroundApi.serviceNotification.ackNotificationMessage({
    msgId: payload.msgId,
    action: ENotificationPushMessageAckAction.arrived,
  });
  void this.backgroundApi.servicePrime.apiFetchPrimeUserInfo();
});

Event Handler Patterns

Simple Acknowledgment + Action

this.socket.on(EAppSocketEventNames.myEvent, (payload: IMyPayload) => {
  void this.backgroundApi.serviceNotification.ackNotificationMessage({
    msgId: payload.msgId,
    action: ENotificationPushMessageAckAction.arrived,
  });
  void this.backgroundApi.someService.doSomething();
});

With Logging

this.socket.on(EAppSocketEventNames.myEvent, (payload: IMyPayload) => {
  defaultLogger.notification.websocket.consoleLog(
    'WebSocket received myEvent:',
    payload,
  );
  void this.backgroundApi.serviceNotification.ackNotificationMessage({
    msgId: payload.msgId,
    action: ENotificationPushMessageAckAction.arrived,
  });
  void this.backgroundApi.someService.doSomething(payload);
});

With Validation

this.socket.on(EAppSocketEventNames.myEvent, async (payload: IMyPayload) => {
  if (!payload?.requiredField) {
    console.error('myEvent ERROR: requiredField is missing', payload);
    return;
  }
  void this.backgroundApi.serviceNotification.ackNotificationMessage({
    msgId: payload.msgId,
    action: ENotificationPushMessageAckAction.arrived,
  });
  await this.backgroundApi.someService.doSomething(payload);
});

With EventBus Emission

this.socket.on(EAppSocketEventNames.myEvent, (payload: IMyPayload) => {
  void this.backgroundApi.serviceNotification.ackNotificationMessage({
    msgId: payload.msgId,
    action: ENotificationPushMessageAckAction.arrived,
  });
  appEventBus.emit(EAppEventBusNames.MyEventReceived, payload);
});

Important: Message Acknowledgment

You MUST acknowledge messages via

serviceNotification.ackNotificationMessage
. If you don't acknowledge the
msgId
, the server will assume the message was not delivered and will retry sending it repeatedly.

void this.backgroundApi.serviceNotification.ackNotificationMessage({
  msgId: payload.msgId,
  action: ENotificationPushMessageAckAction.arrived,
});

This should be called as early as possible in your event handler to prevent duplicate message delivery.

Acknowledgment Actions

Available actions in

ENotificationPushMessageAckAction
:

  • arrived
    - Message was received (use this for most cases)
  • clicked
    - User clicked the notification

Checklist

  • Event name added to
    EAppSocketEventNames
    enum
  • Payload interface defined with
    msgId: string
  • Payload type imported in
    PushProviderWebSocket.ts
  • Event handler added in
    initWebSocket()
    method
  • Message acknowledged via
    ackNotificationMessage
    (required to prevent server retries)
  • Appropriate service method called to handle the event
  • Logging added if needed for debugging