From decee269ce7307c17f387736a4beed1deb11b857 Mon Sep 17 00:00:00 2001 From: Linus Kendall <5172293+linuskendall@users.noreply.github.com> Date: Mon, 14 Sep 2026 06:20:44 +0000 Subject: [PATCH 1/2] feat(websocket): add voteSubscribe specification --- methods/websocket/voteSubscribe.md | 15 +++++++++++ methods/websocket/voteSubscribe.yaml | 38 ++++++++++++++++++++++++++++ proposals/0059-vote-subscribe.md | 38 ++++++++++++++++++++++++++++ spec-info.yaml | 2 +- 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 methods/websocket/voteSubscribe.md create mode 100644 methods/websocket/voteSubscribe.yaml create mode 100644 proposals/0059-vote-subscribe.md diff --git a/methods/websocket/voteSubscribe.md b/methods/websocket/voteSubscribe.md new file mode 100644 index 0000000..6878902 --- /dev/null +++ b/methods/websocket/voteSubscribe.md @@ -0,0 +1,15 @@ +# voteSubscribe + +WebSocket-only. Subscribe to vote messages. The request returns a numeric subscription id. Agave then sends `voteNotification` notifications on the same connection. + +## Notification wire format + +The notification uses JSON-RPC 2.0 with `params.result` as the payload declared in the paired YAML and `params.subscription` as the id returned by this method. + +## Semantics + +Subscriptions are scoped to the WebSocket connection. Closing the connection cancels them. The reference handler deduplicates compatible active subscriptions and rejects new subscriptions when the node limit is reached. + +## Implementation notes + +[**Agave**](../../implementations/agave.md) implements this method in the [pinned PubSub trait](https://github.com/anza-xyz/agave/blob/6dd9d38771e46103b9680357a855804165612602/rpc/src/rpc_pubsub.rs#L223). Cloudbreak and Superbank do not serve WebSocket subscriptions. diff --git a/methods/websocket/voteSubscribe.yaml b/methods/websocket/voteSubscribe.yaml new file mode 100644 index 0000000..46d1e7c --- /dev/null +++ b/methods/websocket/voteSubscribe.yaml @@ -0,0 +1,38 @@ +name: voteSubscribe +status: standard +summary: Subscribe to vote messages. +params: [] +result: + name: subscriptionId + summary: Identifier for this connection's subscription. + schema: { $ref: '#/components/schemas/U64' } +errors: + - $ref: '#/components/errors/InternalError' +examples: + - name: basic + summary: Create the subscription. + params: [] + result: + name: subscriptionId + value: 1 +notification: + name: voteNotification + description: Notification payload sent for this subscription. + schema: + type: object + required: [subscription, result] + properties: + subscription: { $ref: '#/components/schemas/U64' } + result: + type: object + required: [votePubkey, slots, hash, timestamp, signature] + properties: + votePubkey: { $ref: '#/components/schemas/Pubkey' } + slots: { type: array, items: { $ref: '#/components/schemas/Slot' } } + hash: { $ref: '#/components/schemas/Hash' } + timestamp: { oneOf: [{ $ref: '#/components/schemas/I64' }, { type: 'null' }] } + signature: { $ref: '#/components/schemas/Signature' } +implementations: + agave: { status: full } + cloudbreak: { status: none } + superbank: { status: none } diff --git a/proposals/0059-vote-subscribe.md b/proposals/0059-vote-subscribe.md new file mode 100644 index 0000000..d48196c --- /dev/null +++ b/proposals/0059-vote-subscribe.md @@ -0,0 +1,38 @@ +--- +number: 0059 +title: Add voteSubscribe +authors: [rpcpool] +status: draft +created: 2026-09-14 +reference-implementations: [https://github.com/anza-xyz/agave/blob/6dd9d38771e46103b9680357a855804165612602/rpc/src/rpc_pubsub.rs#L223] +--- + +# Add voteSubscribe + +## Summary + +Add the voteSubscribe WebSocket RPC method and its voteNotification notification. + +## Motivation + +Agave exposes this public PubSub method. A standard method page lets clients and alternative implementations use one contract. + +## Specification + +Add the paired WebSocket method page. It defines the request, subscription id, notification name and payload, and the connection-scoped lifecycle. + +## Return-type impact + +The subscribe response is a numeric subscription id. Notifications carry the method-specific payload. + +## Compatibility + +This is additive. Agave implements it. Cloudbreak and Superbank do not currently implement WebSocket PubSub. + +## Reference implementation + +[Agave pinned handler](https://github.com/anza-xyz/agave/blob/6dd9d38771e46103b9680357a855804165612602/rpc/src/rpc_pubsub.rs#L223) + +## Security considerations + +Servers must bound active subscriptions and release them when the connection closes. diff --git a/spec-info.yaml b/spec-info.yaml index 892ea85..bca4391 100644 --- a/spec-info.yaml +++ b/spec-info.yaml @@ -1,5 +1,5 @@ title: Solana JSON-RPC API -version: 0.1.0 +version: 0.2.0 license: name: MIT url: https://opensource.org/license/mit/ From 930d7ec5aae9e0885f9c0f172c9d944495258d1b Mon Sep 17 00:00:00 2001 From: Linus Kendall <5172293+linuskendall@users.noreply.github.com> Date: Mon, 14 Sep 2026 06:42:14 +0000 Subject: [PATCH 2/2] fix(websocket): document disabled subscription error --- methods/websocket/voteSubscribe.md | 4 ++-- methods/websocket/voteSubscribe.yaml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/methods/websocket/voteSubscribe.md b/methods/websocket/voteSubscribe.md index 6878902..a467c7f 100644 --- a/methods/websocket/voteSubscribe.md +++ b/methods/websocket/voteSubscribe.md @@ -8,8 +8,8 @@ The notification uses JSON-RPC 2.0 with `params.result` as the payload declared ## Semantics -Subscriptions are scoped to the WebSocket connection. Closing the connection cancels them. The reference handler deduplicates compatible active subscriptions and rejects new subscriptions when the node limit is reached. +Subscriptions are scoped to the WebSocket connection. Closing the connection cancels them. The reference handler deduplicates compatible active subscriptions and rejects new subscriptions when the node limit is reached. Agave returns `MethodNotFound` unless the validator enables `--rpc-pubsub-enable-vote-subscription`. ## Implementation notes -[**Agave**](../../implementations/agave.md) implements this method in the [pinned PubSub trait](https://github.com/anza-xyz/agave/blob/6dd9d38771e46103b9680357a855804165612602/rpc/src/rpc_pubsub.rs#L223). Cloudbreak and Superbank do not serve WebSocket subscriptions. +[**Agave**](../../implementations/agave.md) implements this method in the [pinned PubSub trait](https://github.com/anza-xyz/agave/blob/6dd9d38771e46103b9680357a855804165612602/rpc/src/rpc_pubsub.rs#L223). diff --git a/methods/websocket/voteSubscribe.yaml b/methods/websocket/voteSubscribe.yaml index 46d1e7c..9c19926 100644 --- a/methods/websocket/voteSubscribe.yaml +++ b/methods/websocket/voteSubscribe.yaml @@ -7,6 +7,7 @@ result: summary: Identifier for this connection's subscription. schema: { $ref: '#/components/schemas/U64' } errors: + - $ref: '#/components/errors/MethodNotFound' - $ref: '#/components/errors/InternalError' examples: - name: basic