feat(mwa-v2): complete MWA v2 rewrite with docs#7
Open
Zurcusa wants to merge 29 commits into
Open
Conversation
- CapabilitiesResult JSON + Response envelope - Deauthorize/GetCapabilities request shape via mock sender - IAdapterOperations reflection contract + [Preserve] - PlayerPrefs migration via MigrateLegacyPrefKeys reflection Refs magicblock-labs#269
Stable GUIDs for Unity import and cross-machine consistency.
- Assert Deauthorize/GetCapabilities payloads via JObject so JsonProperty drift can't hide broken wire keys - Snapshot/restore MWA PlayerPrefs keys so EditMode runs don't wipe dev state
7c20faf to
c92dac5
Compare
…a-keepConnectionAlive-tests Feat(test)/mwa keep connection alive tests
67e50a7 to
8863367
Compare
- Guard null/empty address in PrimaryAccountPublicKeyBytes - Private constructors on DeauthorizeResult and ReconnectResult - Null-result check in JsonRpc20Client.ReceiverRaw - Cache auth token refresh in sign_and_send authorize action - LogoutSuppressed + OnWalletDisconnected on auth revocation paths - Fix base64 → base58 typo in method reference
- Guard null/empty address in PrimaryAccountPublicKeyBytes - Private constructors on DeauthorizeResult and ReconnectResult - Null-result check in JsonRpc20Client.ReceiverRaw - Cache auth token refresh in sign_and_send authorize action - LogoutSuppressed + OnWalletDisconnected on auth revocation paths - Fix base64 → base58 typo in method reference
- Return base58-encoded signatures instead of base64 (Solana RPC compat) - Remove duplicate sendOptions wire field (MWA v2 spec uses "options" only) - Gate Debug.Log wire messages behind UNITY_EDITOR || MWA_VERBOSE_WIRE - Remove unused LegacyPkKey constant from PlayerPrefsAuthorizationCache - Make _warnedThisSession static for once-per-session semantics - Add SIWS fallback length guard for signed payloads < 64 bytes - Enable BouncyCastle for Editor platform (fixes EditMode test loading) - Add namespace to JsonRpcErrorCodes - Fix SchemaVersion default to match ExpectedSchemaVersion (2) - Fix DeauthorizeTests missing _gate reflection init (4 test failures) - Fix ConcurrencyTests assertion for GetUninitializedObject compatibility - Fix ReconnectTests platform guard for non-Android EditMode runs - Remove invalid LegacyPk_DeletedOnConstruction test
- DeauthorizeRequestWireTest: use RpcMethodNames.Deauthorize in assertion instead of hardcoded string - ReconnectTests: promote _gate lookup to static field with OneTimeSetUp guard so reflection drift fails fast with a clear message
LoginWithSignInInternal SIWS fallback was the last AuthorizeAsync call site that discarded the return value, losing token rotations.
- Null-safe constructor: default solanaWalletOptions to prevent NPE - Validate payload elements are non-null before sending to wallet - Treat missing auth_token in clone_authorization as protocol error - Use LoadValidCachedRecordAsync in ReloadAuthTokenFromCacheIfNeeded to enforce schema/chain validation on cached records - Guard null authorization in ReconnectInternal success path - Remove unused using in ConcurrencyTests
Semaphore gate: - Wrap _Login, _SignAllTransactions, SignMessage, GetCapabilities in TryAcquireGate/ReleaseGate to prevent concurrent state corruption Bug fixes: - Preserve WaitForCommitmentToSendNextTransaction when backfilling MinContextSlot - Set WalletBase.Account on LoginWithSignIn success - Default null mwaOptions in SolanaWalletAdapter so cache injection works Upstream PR magicblock-labs#283 test compat: - Update IAdapterOperationsContractTests for v2 AuthorizeAsync API - Rewrite SolanaMobileWalletAdapterPrefsTests for v2 cache-based migration - Fix MobileWalletAdapterClientLifecycleTests Authorize → AuthorizeAsync
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Complete rewrite of the Mobile Wallet Adapter (MWA) implementation from v1 to v2. 120 files changed, ~4200 additions across types, wire protocol, client, adapter, cache, tests, and documentation.
Individual PRs (for granular review)
PlayerPrefsAuthorizationCache, response parser with size caps, 9 test suitesSolanaMobileWalletAdapterrewrite: session lifecycle, SIWS, concurrency gate, silent reconnect, 5 test suitesWhat Changed
Core Types (PR #3)
AccountInfo,AuthorizationRecord,SignInPayload,SignInResult,SendOptionsIAuthorizationCacheinterface (#272)DeauthorizeResult,ReconnectResult,SignAndSendTxResultJsonRpcException,OperationInFlightException,TransportExceptionWire Protocol + Client (PR #4)
chainidentifiers and backward-compatclusterfieldAuthorizeAsyncwith SIWS,DeauthorizeAsync,SignAndSendTransactionsAsync,CloneAuthorizationAsyncAuthorizationResponseParserwith permissive parsing and size caps for untrusted wallet dataPlayerPrefsAuthorizationCachewith scoped keys, schema versioning, corrupt-JSON recoveryAdapter (PR #5)
Disconnect(),Reconnect()(4-state result),Deauthorize()(tri-state),GetCapabilities(),LoginWithSignIn(SignInPayload),SignAndSendTransactions(Transaction[], SendOptions)SemaphoreSlim(1,1)prevents overlapping wallet calls"pk"/"authToken"and PR#269 keys to new cacheDocumentation (PR #6)
mwa-quick-start.md— install, configure, first connectionmwa-method-reference.md— all 13 public methods with signatures and result variantsmwa-cache-guide.md— IAuthorizationCache interface, default/custom implementationsmwa-migration-v1-to-v2.md— v1 → v2 migration guidesign-and-send-investigation.md— Backpack failure analysisKnown Issue: Backpack
sign_and_send_transactionssign_and_send_transactionsfails with Backpack wallet. The transaction is successfully created, signed, and submitted on-chain — the issue is only in receiving the response back in the dApp. Backpack's WebSocket server crashes during the RPC submission phase, corrupting the local association before the response can be delivered. The dApp's pending request hangs indefinitely. This is a Backpack-specific issue — Phantom and Solflare handle the same flow correctly, surviving 8–12 seconds of Android activity STOP without any WebSocket errors.sign_transactionsworks with all wallets including Backpack (no RPC submission involved). Full investigation:docs/sign-and-send-investigation.mdPre-existing
LocalAssociationScenarioIssuesThese issues exist in the upstream
LocalAssociationScenario.csand are outside the scope of this rewrite:returninExecuteNextAction(line 134-135): Falls through to_actions.Dequeue()on an empty queue afterCloseAssociation().OnClosereconnect loop (line 46-50): No delay, no retry limit, no close-awareness. Thread pool storm when the wallet server is gone.TimeSpan.FromSeconds(9000)= 2.5-hour timeout instead of 9 seconds.scenarioResultaccess:scenarioResult.WasSuccessfulthrows if scenario returns null.Breaking Changes
IAdapterOperations.Authorize()andReauthorize()removed — useAuthorizeAsync()AuthorizationResult.PublicKeyandAccountLabelremoved — useAuthorizationHelpers.PrimaryAccountPublicKeyBytes()andPrimaryAccount().LabelDemo App
https://github.com/Zurcusa/unity-solana-mwa-example
Testing Matrix
Tested on Pixel 7 emulator and Solana Seeker (real device).
Wallets Tested
Functionality Coverage