Skip to content

feat: Add StarkNet v0.9+ subscription support and update RPC specs - #2318

Open
EliasiOfir wants to merge 4 commits into
mainfrom
starknet-spec
Open

feat: Add StarkNet v0.9+ subscription support and update RPC specs#2318
EliasiOfir wants to merge 4 commits into
mainfrom
starknet-spec

Conversation

@EliasiOfir

Copy link
Copy Markdown
Collaborator

Description

This PR adds support for StarkNet v0.9+ subscription APIs and updates the mainnet and testnet RPC specifications to reflect the latest StarkNet protocol changes.

Key Changes

StarkNet Subscription Support

  • Added new subscription notification handler (handleSubscriptionResultStarknet) in handler.go to process StarkNet v0.9+ style notifications with the envelope format {method: starknet_subscription*, params: {subscription_id, result}}
  • Added notification detection (isStarknetNotification()) in json.go to identify StarkNet subscription notifications by method prefix starknet_subscription
  • Added comprehensive end-to-end test (TestStarknetSubscriptionEndToEnd) in new file starknet_subscription_test.go that validates the full subscription lifecycle including subscription ID tracking and notification delivery
  • Updated subscription parameter handling in client.go to support StarkNet's by-name parameter style (map-based) in addition to Tendermint's query-based subscriptions

RPC Specification Updates

  • Updated API versions: Migrated from v0.8/v0.9 to v0.9/v0.10 across mainnet and testnet specs
  • Added new RPC methods:
    • starknet_getBlockWithReceipts (20 compute units)
    • starknet_getCompiledCasm (100 compute units)
    • starknet_getMessagesStatus (10 compute units)
    • starknet_getStorageProof (20 compute units)
    • starknet_subscribeEvents, starknet_subscribeNewHeads, starknet_subscribeNewTransactionReceipts, starknet_subscribeNewTransactions, starknet_subscribeTransactionStatus (1000 compute units each)
    • starknet_unsubscribe (replacing pathfinder_unsubscribe)
  • Replaced legacy Pathfinder APIs: Removed pathfinder_subscribe, pathfinder_unsubscribe, pathfinder_getProof, and pathfinder_getTransactionStatus in favor of native StarkNet subscription methods
  • Updated block parsing: Changed starknet_getBlockWithTxs parser argument from "1" to "2" for proper block number indexing
  • Updated method parameters: starknet_getTransactionByBlockIdAndIndex now uses proper block parsing with "0" index
  • Fixed determinism: starknet_getTransactionReceipt marked as deterministic (was incorrectly non-deterministic)
  • Adjusted QoS parameters: Updated average_block_time from 30000/32000ms to 2000ms and allowed_block_lag_for_qos_sync from 1-2 to 5 for both mainnet and testnet
  • Removed pending block verification: Removed the pending-block-support verification check that was causing issues

Configuration Examples

  • Updated provider example configurations to use v0.9 and v0.10 RPC endpoints instead of older v0.5-v0.7 versions
  • Simplified WebSocket path configuration (removed explicit /ws path in favor of empty internal-path)

Testing

  • Added TestStarknetSubscriptionEndToEnd to validate subscription flow with mock StarkNet node
  • Added TestIsStarknetNotification to verify notification detection logic
  • Updated TestJsonRpcInternalPathsMultipleVersionsStarkNet to reflect new API versions
  • All existing tests pass with the updated specifications

Files Changed

  • specs/mainnet-1/specs/starknet.json - Updated RPC specs and methods
  • protocol/chainlib/chainproxy/rpcclient/handler.go - Added StarkNet subscription handler
  • protocol/chainlib/chainproxy/rpcclient/json.go - Added StarkNet notification detection
  • protocol/chainlib/chainproxy/rpcclient/client.go - Updated subscription parameter handling
  • `

https://claude.ai/code/session_01MC6w48eT5tW9K8iUNCm7PG

claude added 3 commits July 20, 2026 16:05
Starknet 0.14.3 (and pathfinder v0.23.0, released 2026-07-20) removed
JSON-RPC v0.8 and older; nodes now serve v0.9 (root default) and v0.10
(final v0.10.1 spec on the v0_10 routes). Update STRK and STRKS specs
accordingly:

- add /rpc/v0_10 and /ws/rpc/v0_10 collections (inheritance-only,
  mirroring the v0_9 pair)
- remove the /rpc/v0_8 and /ws/rpc/v0_8 collections (RPC 0.8 removed
  by Starknet 0.14.3; pathfinder no longer serves these endpoints)
- add missing spec methods: starknet_getBlockWithReceipts,
  starknet_getCompiledCasm, starknet_getMessagesStatus,
  starknet_getStorageProof
- remove starknet_pendingTransactions (dropped from the RPC spec; no
  served version supports it)
- replace the legacy pathfinder_subscribe/pathfinder_unsubscribe WS API
  (removed in pathfinder 0.18.0) with the spec WS subscription family:
  starknet_subscribeNewHeads/Events/TransactionStatus/NewTransactions/
  NewTransactionReceipts + starknet_unsubscribe, one SUBSCRIBE parse
  directive per method (solana-style)
- pathfinder extension collection: drop pathfinder_getProof and
  pathfinder_getTransactionStatus (removed in pathfinder 0.17.0,
  superseded by starknet_getStorageProof/starknet_getTransactionStatus),
  add pathfinder_lastL1AcceptedBlockHashAndNumber
- average_block_time 30000/32000 -> 2000 for Starknet 0.14.x fast
  blocks (matches base/optimism convention for ~2s chains)

Update TestJsonRpcInternalPathsMultipleVersionsStarkNet to the new path
set and refresh the starknet provider example configs (v0_9/v0_10).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MC6w48eT5tW9K8iUNCm7PG
The starknet_subscribe* APIs added to the spec need runtime support the
node ws client lacked:

- notifications use methods named starknet_subscriptionXxx with params
  {subscription_id, result}; none of the existing dispatch shapes
  (ethereum "_subscription" suffix, solana "Notification" suffix,
  legacy pathfinder top-level result) matched, so they were silently
  dropped. Add a dedicated predicate and handler keyed by
  params.subscription_id.
- Client.Subscribe rejected the canonical starknet subscribe forms:
  by-name object params without a tendermint "query" key errored, and
  omitted params hit "unknown parameters type". Make "query" optional
  (tendermint-only) and accept nil params.

Also apply spec calibration from review: starknet_estimateFee block_id
positional index 1 -> 2 (v0.9/v0.10 params are [request,
simulation_flags, block_id]) and allowed_block_lag_for_qos_sync -> 5,
matching the base/optimism convention for ~2s block chains now that
average_block_time is 2000.

Adds predicate unit tests and an end-to-end mock-node websocket test
covering object params, string subscription ids, envelope delivery and
unknown-id drops.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MC6w48eT5tW9K8iUNCm7PG
handleResponse sent op.resp <- msg before writing op.err and
registering the subscription in clientSubs, racing with requestOp.wait
which reads op.err immediately after receiving. On an error response
the caller could observe a stale nil error and treat a failed
subscription as successful. The race was previously unreachable in
tests; the new starknet subscription end-to-end test tripped it
deterministically under -race.

Move all op.err writes and subscription registration before the op.resp
send for subscription responses (matching upstream go-ethereum's
ordering) while preserving this fork's behavior of returning the raw
response message to the caller.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MC6w48eT5tW9K8iUNCm7PG
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add StarkNet v0.9+ WS subscriptions and refresh RPC v0.9/v0.10 specs

✨ Enhancement 🧪 Tests ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add StarkNet v0.9+ websocket notification handling for starknet_subscription* envelopes.
• Update StarkNet RPC specs to v0.9/v0.10 methods, parsing, and QoS defaults.
• Refresh provider examples and tests to use /rpc and /ws rpc v0_9/v0_10 paths.
Diagram

graph TD
  A["rpcclient.Client.Subscribe"] --> B["WS request (starknet_subscribe*)"] --> C["handler.handleResponse"] --> D["Register sub by response id"] --> E["WS notification"] --> F["JsonrpcMessage.isStarknetNotification"] --> G["handler.handleSubscriptionResultStarknet"] --> H["Deliver to sub channel"]
  I["specs/starknet.json v0_9/v0_10"] --> B
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Unify subscription envelopes via a registry/strategy
  • ➕ Avoids adding a new handler branch per chain/protocol variant
  • ➕ Makes it easier to add future StarkNet envelopes (e.g., reorg variants) without widening handler.go
  • ➖ More abstraction and indirection for a small number of supported formats
  • ➖ Requires designing a stable interface for method/params parsing across chains
2. Key StarkNet subscriptions by requested method+params instead of response id
  • ➕ Would not depend on the subscribe response returning a usable id
  • ➕ Might simplify matching if servers ever change id formatting
  • ➖ Less correct for StarkNet’s actual contract (server-assigned subscription ids)
  • ➖ Harder to handle duplicate identical subscriptions cleanly

Recommendation: Keep the PR’s approach: it matches StarkNet v0.9+ semantics (server returns subscription id; notifications carry subscription_id) and is minimally invasive to existing Ethereum/Tendermint/Solana handling. If more chain-specific WS formats are expected soon, consider introducing a small notification-parsing strategy interface to reduce future branching in handler.handleImmediate.

Files changed (11) +555 / -175

Enhancement (3) +45 / -8
client.goAllow StarkNet-style subscriptions without query-keyed sub ids +5/-5

Allow StarkNet-style subscriptions without query-keyed sub ids

• Relaxes the map-param subscription flow to only use the 'query' field when present (Tendermint), instead of failing for other chains. Adds explicit nil-params support so Subscribe can omit params cleanly via omitempty.

protocol/chainlib/chainproxy/rpcclient/client.go

handler.goDispatch StarkNet v0.9+ notifications and fix subscribe response ordering +26/-3

Dispatch StarkNet v0.9+ notifications and fix subscribe response ordering

• Adds a StarkNet notification branch in the immediate handler path and a dedicated handler that unmarshals params into {subscription_id,result} and delivers to the matching subscriber. Also adjusts response handling to ensure subscription registration and error assignment happen before unblocking the waiting caller (avoids races).

protocol/chainlib/chainproxy/rpcclient/handler.go

json.goAdd StarkNet notification detection and params envelope struct +14/-0

Add StarkNet notification detection and params envelope struct

• Introduces a starknet_subscription* method prefix constant, a params struct carrying subscription_id, and an isStarknetNotification() predicate. This differentiates StarkNet v0.9+ envelopes from Ethereum suffix-based notifications and legacy Pathfinder top-level-result messages.

protocol/chainlib/chainproxy/rpcclient/json.go

Tests (2) +134 / -5
starknet_subscription_test.goAdd unit + end-to-end tests for StarkNet subscription lifecycle +129/-0

Add unit + end-to-end tests for StarkNet subscription lifecycle

• Adds coverage for StarkNet notification detection and an end-to-end websocket test using a mock server. Validates by-name subscribe params, response-derived subscription id tracking, correct notification delivery, and silent dropping of unknown subscription ids.

protocol/chainlib/chainproxy/rpcclient/starknet_subscription_test.go

jsonRPC_test.goUpdate StarkNet internal-path version test to v0_9/v0_10 +5/-5

Update StarkNet internal-path version test to v0_9/v0_10

• Adjusts the StarkNet multi-version internal path test to remove v0_8 expectations and add v0_10. Verifies that parsing selects the correct collection based on /rpc/v0_9 and /rpc/v0_10 internal paths.

protocol/chainlib/jsonRPC_test.go

Other (6) +376 / -162
starknet_auto_complete_with_addon.ymlBump StarkNet WS example endpoints to v0_9/v0_10 +4/-4

Bump StarkNet WS example endpoints to v0_9/v0_10

• Updates websocket RPC internal paths from v0_6/v0_7 to v0_9/v0_10 in the cookbook example that includes addons. Keeps the base /ws endpoint entry while aligning versioned paths with the new spec.

config/provider_examples/provider_example_cookbook/starknet_auto_complete_with_addon.yml

starknet_auto_complete_without_addons.ymlBump StarkNet WS example endpoints to v0_9/v0_10 (no addons) +4/-4

Bump StarkNet WS example endpoints to v0_9/v0_10 (no addons)

• Updates websocket RPC internal paths to use /ws/rpc/v0_9 and /ws/rpc/v0_10 instead of older versions. Ensures example remains compatible with nodes that no longer serve v0_6/v0_7.

config/provider_examples/provider_example_cookbook/starknet_auto_complete_without_addons.yml

starknet_example_full_internal_path.ymlRefresh StarkNet internal-path examples for v0_9/v0_10 +11/-13

Refresh StarkNet internal-path examples for v0_9/v0_10

• Cleans up comment whitespace and updates the example to drop older v0_5-v0_7 paths. Sets the base /ws internal-path to empty and adds explicit /rpc and /ws rpc v0_9/v0_10 entries.

config/provider_examples/provider_example_cookbook/starknet_example_full_internal_path.yml

strk_addon_example_with_ws.ymlShift STRK addon WS internal paths to v0_9/v0_10 +2/-2

Shift STRK addon WS internal paths to v0_9/v0_10

• Updates the example websocket internal paths from v0_8/v0_9 to v0_9/v0_10 to match the new StarkNet JSON-RPC versioning. Preserves the same base provider URLs.

config/provider_examples/strk_addon_example_with_ws.yml

strk_example.ymlUpdate STRK provider example to v0_9/v0_10 paths +9/-11

Update STRK provider example to v0_9/v0_10 paths

• Removes deprecated v0_5-v0_7 internal-path entries and replaces them with /rpc and /ws rpc v0_9/v0_10. Sets the base /ws internal-path to empty for consistency with other examples.

config/provider_examples/strk_example.yml

starknet.jsonRefresh StarkNet mainnet/testnet RPC collections for v0.9/v0.10 + WS subs +346/-128

Refresh StarkNet mainnet/testnet RPC collections for v0.9/v0.10 + WS subs

• Updates QoS defaults (average_block_time and allowed_block_lag_for_qos_sync), adds v0_10 and removes v0_8 internal paths, and expands the method set with new core RPCs and StarkNet-native websocket subscriptions/unsubscribe. Fixes block parsing indices for select APIs, marks getTransactionReceipt deterministic, removes pending transaction API entries, and drops the pending-block-support verification check.

specs/mainnet-1/specs/starknet.json

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 52.17391% with 11 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
protocol/chainlib/chainproxy/rpcclient/handler.go 47.05% 8 Missing and 1 partial ⚠️
protocol/chainlib/chainproxy/rpcclient/client.go 33.33% 2 Missing ⚠️
Flag Coverage Δ
consensus 8.96% <ø> (ø)
protocol 39.56% <52.17%> (+0.91%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
protocol/chainlib/chainproxy/rpcclient/json.go 31.54% <100.00%> (+31.54%) ⬆️
protocol/chainlib/chainproxy/rpcclient/client.go 35.44% <33.33%> (+23.31%) ⬆️
protocol/chainlib/chainproxy/rpcclient/handler.go 18.90% <47.05%> (+18.90%) ⬆️

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Starknet casing inconsistent 📘 Rule violation ⚙ Maintainability
Description
New StarkNet-related identifiers use mixed casing (StarkNet vs Starknet) within the same
package, which breaks repository naming conventions and makes identifiers harder to discover/grep
consistently. This is visible in the new handleSubscriptionResultStarknet /
isStarknetNotification additions alongside existing ...StarkNet... names.
Code

protocol/chainlib/chainproxy/rpcclient/handler.go[283]

+func (h *handler) handleSubscriptionResultStarknet(msg *JsonrpcMessage) {
Evidence
Rule 2 requires Go identifiers to follow repository conventions. In handler.go, existing functions
use StarkNet casing (handleSubscriptionResultStarkNetPathfinder) while the new additions
introduce Starknet casing (isStarknetNotification, handleSubscriptionResultStarknet),
demonstrating an inconsistent convention within the same package.

AGENTS.md: Go Identifiers, Files, and Protobuf Naming Must Follow Repository Conventions
protocol/chainlib/chainproxy/rpcclient/handler.go[248-297]
protocol/chainlib/chainproxy/rpcclient/json.go[93-103]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
StarkNet-related identifiers were introduced with inconsistent casing (`Starknet` vs `StarkNet`) in the same `rpcclient` package.

## Issue Context
The package already uses `StarkNet` casing in existing identifiers (e.g. `isStarkNetPathfinderNotification`, `handleSubscriptionResultStarkNetPathfinder`). The new functions `isStarknetNotification` and `handleSubscriptionResultStarknet` introduce a second style, which violates repository naming conventions and reduces consistency.

## Fix Focus Areas
- protocol/chainlib/chainproxy/rpcclient/handler.go[254-297]
- protocol/chainlib/chainproxy/rpcclient/json.go[93-103]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Tests not TestX_Y named 📘 Rule violation ⚙ Maintainability
Description
The newly added tests do not follow the required TestComponent_Scenario naming convention (missing
underscore-separated component/scenario). This reduces consistency and makes test intent/grouping
harder to scan.
Code

protocol/chainlib/chainproxy/rpcclient/starknet_subscription_test.go[R16-67]

+func TestIsStarknetNotification(t *testing.T) {
+	notification := &JsonrpcMessage{
+		Version: Vsn,
+		Method:  "starknet_subscriptionNewHeads",
+		Params:  json.RawMessage(`{"subscription_id":"340282366920938463463374607431768211456","result":{"block_number":5}}`),
+	}
+	require.True(t, notification.isStarknetNotification())
+	require.False(t, notification.isEthereumNotification())
+	require.False(t, notification.isStarkNetPathfinderNotification())
+	require.False(t, notification.isTendermintNotification())
+
+	for _, method := range []string{
+		"starknet_subscriptionEvents",
+		"starknet_subscriptionTransactionStatus",
+		"starknet_subscriptionNewTransactionReceipts",
+		"starknet_subscriptionNewTransaction",
+		"starknet_subscriptionReorg",
+	} {
+		msg := &JsonrpcMessage{Version: Vsn, Method: method, Params: json.RawMessage(`{"subscription_id":"1","result":{}}`)}
+		require.True(t, msg.isStarknetNotification(), method)
+	}
+
+	// ethereum-style notification must not match
+	ethNotification := &JsonrpcMessage{
+		Version: Vsn,
+		Method:  "eth_subscription",
+		Params:  json.RawMessage(`{"subscription":"0x1","result":{}}`),
+	}
+	require.False(t, ethNotification.isStarknetNotification())
+
+	// a starknet_subscribe* response has no method, must not match
+	response := &JsonrpcMessage{
+		Version: Vsn,
+		ID:      json.RawMessage(`1`),
+		Result:  json.RawMessage(`"340282366920938463463374607431768211456"`),
+	}
+	require.False(t, response.isStarknetNotification())
+
+	// legacy pathfinder notification (top-level result) must not match
+	pathfinderNotification := &JsonrpcMessage{
+		Version: Vsn,
+		Method:  "pathfinder_subscription",
+		Result:  json.RawMessage(`{"subscription":1,"result":{}}`),
+	}
+	require.False(t, pathfinderNotification.isStarknetNotification())
+}
+
+// TestStarknetSubscriptionEndToEnd subscribes against a mock starknet node over
+// websocket using by-name params (the canonical starknet form) and verifies the
+// v0.9+ notification envelope {method: starknet_subscriptionXxx, params:
+// {subscription_id, result}} is delivered to the subscription channel.
+func TestStarknetSubscriptionEndToEnd(t *testing.T) {
Evidence
Rule 4 requires new/updated unit tests to follow the TestComponent_Scenario naming convention. The
added test functions are named TestIsStarknetNotification and TestStarknetSubscriptionEndToEnd,
which do not match the required pattern.

AGENTS.md: Test Changes Must Include and Follow Table-Driven Test Conventions
protocol/chainlib/chainproxy/rpcclient/starknet_subscription_test.go[16-67]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
New tests are not named using the required `TestComponent_Scenario` convention.

## Issue Context
The compliance checklist requires new/updated tests to be named like `TestComponent_Scenario`. The added tests are currently named `TestIsStarknetNotification` and `TestStarknetSubscriptionEndToEnd`.

## Fix Focus Areas
- protocol/chainlib/chainproxy/rpcclient/starknet_subscription_test.go[16-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Silent tendermint query failure 🐞 Bug ≡ Correctness
Description
Client.Subscribe no longer errors when map params contain a missing/non-string query, which can
register a Tendermint subscription under the server-returned id instead of the query and then drop
all notifications (which are routed by result.query). This regresses prior behavior where
malformed Tendermint subscription params failed fast with a clear error, making broken subscriptions
harder to diagnose.
Code

protocol/chainlib/chainproxy/rpcclient/client.go[R510-515]

		msg, err = c.newMessageMapWithID(method, id, p)
-		subId, ok = p["query"].(string)
-		if !ok {
-			return nil, nil, fmt.Errorf("Subscribe - p['query'].(string) - type assertion failed")
-		}
+		// tendermint subscriptions are keyed by their "query" param; other chains
+		// using by-name params (e.g. starknet) get their id from the response
+		subId, _ = p["query"].(string)
+	case nil:
+		msg, err = c.newMessageArrayWithID(method, id, nil) // pass nil to let omitempty tag handle field omission
Evidence
Tendermint notifications are dispatched by result.query, so subscriptions must be registered in
clientSubs under that query string. handleResponse only registers under op.subId when it is
non-empty; if subId is left empty (due to ignored type assertion), it instead registers under the
response result id, which won’t match Tendermint notification routing.

protocol/chainlib/chainproxy/rpcclient/client.go[491-528]
protocol/chainlib/chainproxy/rpcclient/handler.go[330-343]
protocol/chainlib/chainproxy/rpcclient/handler.go[346-387]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`Client.Subscribe` now does `subId, _ = p["query"].(string)` for map-based params. If a Tendermint subscription is passed with a malformed `query` (wrong type) or an unexpected shape, `subId` becomes empty, and `handleResponse` will register the subscription under the response `result` instead. Tendermint notifications are delivered by `result.query`, so the client will silently drop notifications.

### Issue Context
- Tendermint notifications are routed by `result.query` (not by subscription id).
- `handleResponse` registers by `op.subId` only when non-empty.
- StarkNet named params should still be supported (no `query` key).

### Fix Focus Areas
- protocol/chainlib/chainproxy/rpcclient/client.go[505-518]

### Suggested fix
In the `case map[string]interface{}` branch:
- If the `query` key is **present**:
 - Require it to be a `string` (return the prior type-assertion error if not).
 - Set `subId` to that string.
- If the `query` key is **absent**:
 - Leave `subId` empty so non-Tendermint chains (e.g. StarkNet) use the response `result` as the subscription id.

This preserves the StarkNet-by-name behavior while restoring fail-fast safety for Tendermint-shaped params.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

}
}

func (h *handler) handleSubscriptionResultStarknet(msg *JsonrpcMessage) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. starknet casing inconsistent 📘 Rule violation ⚙ Maintainability

New StarkNet-related identifiers use mixed casing (StarkNet vs Starknet) within the same
package, which breaks repository naming conventions and makes identifiers harder to discover/grep
consistently. This is visible in the new handleSubscriptionResultStarknet /
isStarknetNotification additions alongside existing ...StarkNet... names.
Agent Prompt
## Issue description
StarkNet-related identifiers were introduced with inconsistent casing (`Starknet` vs `StarkNet`) in the same `rpcclient` package.

## Issue Context
The package already uses `StarkNet` casing in existing identifiers (e.g. `isStarkNetPathfinderNotification`, `handleSubscriptionResultStarkNetPathfinder`). The new functions `isStarknetNotification` and `handleSubscriptionResultStarknet` introduce a second style, which violates repository naming conventions and reduces consistency.

## Fix Focus Areas
- protocol/chainlib/chainproxy/rpcclient/handler.go[254-297]
- protocol/chainlib/chainproxy/rpcclient/json.go[93-103]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

"github.com/stretchr/testify/require"
)

func TestIsStarknetNotification(t *testing.T) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Tests not testx_y named 📘 Rule violation ⚙ Maintainability

The newly added tests do not follow the required TestComponent_Scenario naming convention (missing
underscore-separated component/scenario). This reduces consistency and makes test intent/grouping
harder to scan.
Agent Prompt
## Issue description
New tests are not named using the required `TestComponent_Scenario` convention.

## Issue Context
The compliance checklist requires new/updated tests to be named like `TestComponent_Scenario`. The added tests are currently named `TestIsStarknetNotification` and `TestStarknetSubscriptionEndToEnd`.

## Fix Focus Areas
- protocol/chainlib/chainproxy/rpcclient/starknet_subscription_test.go[16-67]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

case []interface{}:
msg, err = c.newMessageArrayWithID(method, id, p)
case map[string]interface{}:
msg, err = c.newMessageMapWithID(method, id, p)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

3. Silent tendermint query failure 🐞 Bug ≡ Correctness

Client.Subscribe no longer errors when map params contain a missing/non-string query, which can
register a Tendermint subscription under the server-returned id instead of the query and then drop
all notifications (which are routed by result.query). This regresses prior behavior where
malformed Tendermint subscription params failed fast with a clear error, making broken subscriptions
harder to diagnose.
Agent Prompt
### Issue description
`Client.Subscribe` now does `subId, _ = p["query"].(string)` for map-based params. If a Tendermint subscription is passed with a malformed `query` (wrong type) or an unexpected shape, `subId` becomes empty, and `handleResponse` will register the subscription under the response `result` instead. Tendermint notifications are delivered by `result.query`, so the client will silently drop notifications.

### Issue Context
- Tendermint notifications are routed by `result.query` (not by subscription id).
- `handleResponse` registers by `op.subId` only when non-empty.
- StarkNet named params should still be supported (no `query` key).

### Fix Focus Areas
- protocol/chainlib/chainproxy/rpcclient/client.go[505-518]

### Suggested fix
In the `case map[string]interface{}` branch:
- If the `query` key is **present**:
  - Require it to be a `string` (return the prior type-assertion error if not).
  - Set `subId` to that string.
- If the `query` key is **absent**:
  - Leave `subId` empty so non-Tendermint chains (e.g. StarkNet) use the response `result` as the subscription id.

This preserves the StarkNet-by-name behavior while restoring fail-fast safety for Tendermint-shaped params.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown

Test Results

0 tests  ±0   0 ✅ ±0   0s ⏱️ ±0s
0 suites ±0   0 💤 ±0 
7 files   ±0   0 ❌ ±0 

Results for commit 078e162. ± Comparison against base commit c4c16fe.

♻️ This comment has been updated with latest results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants