Skip to content

Jerry/emb 296 magic ios feature pairty headless flow#46

Merged
Ethella merged 4 commits into
mainfrom
jerry/emb-296-magic-ios-feature-pairty-and-bug-fixes
Jun 30, 2026
Merged

Jerry/emb 296 magic ios feature pairty headless flow#46
Ethella merged 4 commits into
mainfrom
jerry/emb-296-magic-ios-feature-pairty-and-bug-fixes

Conversation

@Ethella

@Ethella Ethella commented Jun 30, 2026

Copy link
Copy Markdown
Member
image

@Ethella Ethella changed the title Jerry/emb 296 magic ios feature pairty and bug fixes Jerry/emb 296 magic ios feature pairty headless flow Jun 30, 2026
@Ethella Ethella requested review from Copilot and joshuascan June 30, 2026 00:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the Magic iOS SDK toward feature parity for headless (event-driven) auth flows and adds new platform capabilities (EVM chain switching), while also improving relayer robustness (heartbeat/ping-pong) and key storage behavior.

Changes:

  • Add event-driven (PromiEvent-like) auth flow support for Email OTP (emit intermediary events; persistent event subscriptions; error subscriptions).
  • Add EVM extension with switchChain, plus new user methods/config fields (MFA enable/disable, showUI flags).
  • Improve relayer stability via heartbeat ping/pong and make RPC response handling more robust; adjust keychain item accessibility and synchronizable flags.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Sources/MagicSDK/Utilities/SEKP.swift Tightens keychain accessibility to ...ThisDeviceOnly and forces non-synchronizable key storage/lookup.
Sources/MagicSDK/Modules/Wallet/WalletConfiguration.swift Minor formatting cleanup.
Sources/MagicSDK/Modules/User/UserModule.swift Updates isLoggedIn method name; adds MFA enable/disable RPC methods.
Sources/MagicSDK/Modules/User/UserMethod.swift Renames/adds RPC method strings (isLoggedIn, MFA, metadata).
Sources/MagicSDK/Modules/User/UserConfiguration.swift Adds showUI to recover account configuration for headless/UI control.
Sources/MagicSDK/Modules/EVM/EVMMethod.swift Introduces EVM RPC method enum.
Sources/MagicSDK/Modules/EVM/EVMExtension.swift Adds public Magic.evm.switchChain module API (Promise + callback).
Sources/MagicSDK/Modules/EVM/EVMConfiguration.swift Adds switch-chain request/response models and EVM network configuration struct.
Sources/MagicSDK/Modules/Event/EventPromise.swift Adds PromiEvent-like API (on, onPersistent, onError, emit, chaining catch) and changes once-subscription naming.
Sources/MagicSDK/Modules/Event/EventCenter.swift Adds support for once vs persistent observers and observer cleanup helper.
Sources/MagicSDK/Modules/BaseModule.swift Adds intermediary-event RPC sender to support headless flows.
Sources/MagicSDK/Modules/Auth/AuthModule.swift Adds event-driven loginWithEmailOTP(showUI:false) overload and new event enum set.
Sources/MagicSDK/Modules/Auth/AuthConfiguration.swift Expands auth configs with showUI, overrides, and lifespan options.
Sources/MagicSDK/Core/Relayer/WebViewController.swift Adds heartbeat ping/pong, improves key window discovery, robust JSON id extraction, and event re-wrapping.
Sources/MagicSDK/Core/Relayer/Types/BasicTypes.swift Adds MAGIC_PING/MAGIC_PONG message types and supports refresh token field on responses.
Sources/MagicSDK/Core/Provider/RpcProvider.swift Stops regenerating request IDs; adds refresh token persistence and attaches rt/jwt to outbound relayer messages.
README.md Updates documentation to point to SwiftUI example app.
.swiftpm/xcode/xcshareddata/xcschemes/MagicSDK.xcscheme Adds shared Xcode scheme.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Sources/MagicSDK/Core/Provider/RpcProvider.swift Outdated
Comment on lines +141 to +143
// Re-wrap as MagicEventResult<[AnyValue]> (non-optional params) so EventCenter cast succeeds
let result = MagicEventResult<[AnyValue]>(event: eventName, params: event.result.params ?? [], product_announcement: event.result.product_announcement)
NotificationCenter.default.post(name: Notification.Name.init(eventName), object: nil, userInfo: ["event": result])
Comment thread Sources/MagicSDK/Modules/Event/EventCenter.swift
Comment thread Sources/MagicSDK/Modules/Event/EventPromise.swift

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 18 out of 18 changed files in this pull request and generated 7 comments.

Comment on lines +96 to +100
public func logout(response: @escaping Web3ResponseCompletion<Bool>) {
let request = BasicRPCRequest(method: UserMethod.magic_auth_logout.rawValue, params: [])
self.provider.send(request: request, response: response)
self.provider.send(request: request) { [weak self] (result: Web3Response<Bool>) in
self?.provider.clearRefreshToken()
response(result)
Comment on lines +19 to 24
/// Subscribe to an inbound event (fires once, then unregisters).
@discardableResult
public func on(eventName: String, completion: @escaping () -> Void) -> MagicEventPromise {
eventCenter.addOnceObserver(eventName: eventName, eventLog: eventLog, completion: completion)
return self
}
Comment on lines +26 to +30
func addOnceObserver(eventName: String, eventLog: Bool, completion: @escaping ([AnyValue]?) -> Void) {
NotificationCenter.default.addObserver(self, selector: #selector(self.onDidReceiveEvent(_:)), name: Notification.Name(eventName), object: nil)
self.eventLog = eventLog
onceHandlerDict[eventName] = completion
}
Comment on lines +36 to +39
func addPersistentObserver(eventName: String, eventLog: Bool, completion: @escaping ([AnyValue]?) -> Void) {
NotificationCenter.default.addObserver(self, selector: #selector(self.onDidReceiveEvent(_:)), name: Notification.Name(eventName), object: nil)
self.eventLog = eventLog
eventHandlerDict[eventName] = completion
persistentHandlerDict[eventName] = completion
kSecAttrAccount: account,
kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked,
kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
kSecAttrSynchronizable: kCFBooleanFalse!,
// Seek a generic password with the given account.
let query = [kSecClass: kSecClassGenericPassword,
kSecAttrAccount: account,
kSecAttrSynchronizable: kCFBooleanFalse!,
func deleteKeyFromKeyChain() throws {
let query = [kSecClass: kSecClassGenericPassword,
kSecAttrAccount: account,
kSecAttrSynchronizable: kCFBooleanFalse!,
@Ethella Ethella merged commit 52d84cd into main Jun 30, 2026
1 check passed
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.

3 participants