Skip to content

feat: add GetCapabilities MWA 2.0 method#277

Open
mstevens843 wants to merge 1 commit into
magicblock-labs:mainfrom
mstevens843:feature/get-capabilities
Open

feat: add GetCapabilities MWA 2.0 method#277
mstevens843 wants to merge 1 commit into
magicblock-labs:mainfrom
mstevens843:feature/get-capabilities

Conversation

@mstevens843
Copy link
Copy Markdown
Contributor

@mstevens843 mstevens843 commented Apr 14, 2026

The MWA 2.0 spec defines get_capabilities as a non-privileged method that queries wallet capabilities. This method did not exist in the SDK.

Added GetCapabilities() to the MWA client layer:

  • IAdapterOperations.cs: added GetCapabilities() interface method
  • MobileWalletAdapterClient.cs: sends get_capabilities JSON-RPC request
  • SolanaMobileWalletAdapter.cs: async wrapper via LocalAssociationScenario
  • CapabilitiesResult.cs: response model (MaxTransactionsPerRequest, MaxMessagesPerRequest, SupportedTransactionVersions, Features)

Tested on Solana Seeker with Phantom — returns real values: maxTransactions=10, maxMessages=1, supportedVersions=[legacy, 0], features=[supports_sign_and_send_transactions]

⚠️ NOTE: This is a new MWA 2.0 method that was missing from the SDK. No existing methods were changed. Non-breaking addition.

Status Type ⚠️ Core Change Issue
Ready Feature Yes #273

Problem

The MWA 2.0 spec defines get_capabilities as a non-privileged method for querying wallet limits and supported features. Without it, developers have no way to check how many transactions or messages a wallet can handle per request. Sending more than the wallet supports fails the entire request with
ERROR_TOO_MANY_PAYLOADS and there is no way to prevent it ahead of time.

Solution

Added GetCapabilities() across the MWA client layer following the same pattern as existing methods (authorize, signTransactions, signMessages):

  • IAdapterOperations.cs: added GetCapabilities() to the interface
  • MobileWalletAdapterClient.cs: sends get_capabilities JSON-RPC request over the encrypted session channel
  • SolanaMobileWalletAdapter.cs: async wrapper that handles LocalAssociationScenario lifecycle
  • CapabilitiesResult.cs: new response model with MaxTransactionsPerRequest, MaxMessagesPerRequest, SupportedTransactionVersions, Features

Before & After Screenshots

BEFORE:
No method exists to query wallet capabilities. Developers must guess batch sizes or hardcode limits.

AFTER:
Tested on Solana Seeker with Phantom wallet:

  • MaxTransactionsPerRequest = 10
  • MaxMessagesPerRequest = 1
  • SupportedTransactionVersions = [legacy, 0]
  • Features = [supports_sign_and_send_transactions]

Other changes (e.g. bug fixes, small refactors)

None. Self-contained addition.

Deploy Notes

No new dependencies, scripts, or configuration changes. Pure C# addition to the existing MWA client layer.

New scripts:

  • None

New dependencies:

  • None

Summary by CodeRabbit

  • New Features
    • Enhanced JSON RPC client capabilities. Applications can now query and receive comprehensive feature support information from the Solana Mobile Stack. The system properly handles feature data serialization with optimized null-value management, ensuring clean and efficient API responses for improved developer experience and system interoperability.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 14, 2026

Warning

Rate limit exceeded

@mstevens843 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 59 minutes and 59 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b682d273-2a78-4ed1-9823-fb0deeb70157

📥 Commits

Reviewing files that changed from the base of the PR and between 387f9d1 and 2737e6d.

📒 Files selected for processing (3)
  • Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs
  • Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs.meta
  • Runtime/codebase/SolanaMobileStack/MobileWalletAdapterClient.cs

Walkthrough

A new nullable Features property (string array) was added to the CapabilitiesResult class, mapped to the JSON field "features" with null-value serialization handling. The property uses standard Newtonsoft.Json serialization attributes.

Changes

Cohort / File(s) Summary
CapabilitiesResult Response Model
Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs
Added public Features property (nullable string array) with JSON mapping to "features" field and NullValueHandling.Ignore for serialization.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: adding the GetCapabilities method for MWA 2.0 support to the SDK.
Description check ✅ Passed The PR description comprehensively covers the problem, solution, testing results, and deployment notes following the template structure.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs`:
- Around line 18-24: CapabilitiesResult's collection properties
SupportedTransactionVersions and Features can be deserialized as null and cause
NREs; update the property declarations in the CapabilitiesResult class to
initialize both SupportedTransactionVersions and Features to empty List<string>
instances (e.g., new List<string>()) so consumers can safely iterate without
null checks and keep the existing JsonProperty/RequiredMember attributes intact.

In `@Runtime/codebase/SolanaMobileStack/SolanaMobileWalletAdapter.cs`:
- Around line 191-208: The method captures a CapabilitiesResult into the local
variable capabilities via LocalAssociationScenario.StartAndExecute/
GetCapabilities but may return null even when result.WasSuccessful; after the
call to StartAndExecute and the success check, add a null guard for the
capabilities variable (from this method's local “capabilities”) and handle it
consistently—either throw a descriptive Exception or log an error with
Debug.LogError and throw (e.g., "Capabilities payload was null after successful
association")—so callers never receive a null CapabilitiesResult.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4e9512e0-7855-4ee6-a1a5-218cc1c3b5a7

📥 Commits

Reviewing files that changed from the base of the PR and between 054503e and 28f0757.

📒 Files selected for processing (5)
  • Runtime/codebase/SolanaMobileStack/Interfaces/IAdapterOperations.cs
  • Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs
  • Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs.meta
  • Runtime/codebase/SolanaMobileStack/MobileWalletAdapterClient.cs
  • Runtime/codebase/SolanaMobileStack/SolanaMobileWalletAdapter.cs

Comment thread Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs Outdated
Comment thread Runtime/codebase/SolanaMobileStack/SolanaMobileWalletAdapter.cs Outdated
@Kuldotha
Copy link
Copy Markdown
Contributor

@mstevens843 Hey, thanks for looking into this. I just merged another PR that implements this too however. Can you double check if anything from this PR is still necessary?

@mstevens843 mstevens843 force-pushed the feature/get-capabilities branch from 28f0757 to 387f9d1 Compare April 18, 2026 00:52
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs (1)

20-22: ⚠️ Potential issue | 🟡 Minor

Consider defaulting Features to an empty array.

NullValueHandling.Ignore only affects serialization — on deserialization, if "features" is absent the property remains null, so downstream iteration can NRE. Initialize to Array.Empty<string>() (same applies to SupportedTransactionVersions on Line 19).

Proposed fix
-    [JsonProperty("supported_transaction_versions")]
-    public string[] SupportedTransactionVersions { get; set; }
-
-    [JsonProperty("features", NullValueHandling = NullValueHandling.Ignore)]
-    public string[] Features { get; set; }
+    [JsonProperty("supported_transaction_versions")]
+    public string[] SupportedTransactionVersions { get; set; } = System.Array.Empty<string>();
+
+    [JsonProperty("features", NullValueHandling = NullValueHandling.Ignore)]
+    public string[] Features { get; set; } = System.Array.Empty<string>();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs`
around lines 20 - 22, The Features property (and SupportedTransactionVersions)
can remain null after deserialization when the JSON field is absent, causing
potential NREs; initialize both properties to empty arrays by assigning
Array.Empty<string>() as their default values on their auto-properties (e.g.,
public string[] Features { get; set; } = Array.Empty<string>(); and same for
SupportedTransactionVersions) so consumers can safely enumerate them even when
the JSON omits the fields.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs`:
- Around line 20-22: The Features property (and SupportedTransactionVersions)
can remain null after deserialization when the JSON field is absent, causing
potential NREs; initialize both properties to empty arrays by assigning
Array.Empty<string>() as their default values on their auto-properties (e.g.,
public string[] Features { get; set; } = Array.Empty<string>(); and same for
SupportedTransactionVersions) so consumers can safely enumerate them even when
the JSON omits the fields.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2b70d5b1-747e-4dca-8e6b-a03f238ebfcd

📥 Commits

Reviewing files that changed from the base of the PR and between 28f0757 and 387f9d1.

📒 Files selected for processing (1)
  • Runtime/codebase/SolanaMobileStack/JsonRpcClient/Responses/CapabilitiesResult.cs

@mstevens843
Copy link
Copy Markdown
Contributor Author

Hey @Kuldotha ,

thanks for the heads up on #269. Checked it out and you're right, most of what I had is already covered. I rebased this PR down to just one thing that's still missing though: the features array on CapabilitiesResult.
It's defined in the MWA 2.0 spec and Phantom actually returns it. Tested on my Seeker on mainnet and get_capabilities came back with features: ["supports_sign_and_send_transactions"]. Without the field on the C# model it just gets dropped on deserialization.

So this PR is now a 3-line add to the file from #269, nothing else. If you'd rather just fold it into a future patch yourself, no worries, happy to close it. Otherwise it should be a pretty quick review.

The MWA 2.0 spec defines get_capabilities as a non-privileged method
that queries wallet capabilities. This method did not exist in the SDK.

Added GetCapabilities() to the MWA client layer:
- IAdapterOperations.cs: added GetCapabilities() interface method
- MobileWalletAdapterClient.cs: sends get_capabilities JSON-RPC request
- SolanaMobileWalletAdapter.cs: async wrapper via LocalAssociationScenario
- CapabilitiesResult.cs: response model (MaxTransactionsPerRequest,
  MaxMessagesPerRequest, SupportedTransactionVersions, Features)

Tested on Solana Seeker with Phantom — returns real values:
maxTransactions=10, maxMessages=1, supportedVersions=[legacy, 0],
features=[supports_sign_and_send_transactions]

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@mstevens843 mstevens843 force-pushed the feature/get-capabilities branch from 387f9d1 to 2737e6d Compare April 27, 2026 20:16
@mstevens843
Copy link
Copy Markdown
Contributor Author

Quick update on this one. Rebased onto current main so it sits cleanly on top of #269 now.

After the rebase the diff is exactly the 3-line add I described in the previous comment: just the Features property on CapabilitiesResult, in the same string[] style as the rest of the class. Both CodeRabbit comments from the original review went stale through the rebase (the null guard is already in #269's GetCapabilities, and the collection-init suggestion was for the List shape from before the rebase, not the string[] we ended up with).
Ready whenever you have a minute.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants