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.
git clone https://github.com/majiayu000/claude-skill-registry
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"
skills/data/1k-adding-socket-events/SKILL.mdAdding 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:
- Define the event name in
enumEAppSocketEventNames - Define the payload type interface
- Add the event handler in
PushProviderWebSocket
Key Files
| Purpose | Location |
|---|---|
| Event names & payload types | |
| WebSocket event handlers | |
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:
- Import the new payload type:
import type { // ... existing imports IMyNewEventPayload, } from '@onekeyhq/shared/types/socket';
- Add the event handler in
method:initWebSocket()
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
. If you don't acknowledge the serviceNotification.ackNotificationMessage
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:
- Message was received (use this for most cases)arrived
- User clicked the notificationclicked
Checklist
- Event name added to
enumEAppSocketEventNames - Payload interface defined with
msgId: string - Payload type imported in
PushProviderWebSocket.ts - Event handler added in
methodinitWebSocket() - Message acknowledged via
(required to prevent server retries)ackNotificationMessage - Appropriate service method called to handle the event
- Logging added if needed for debugging