diff --git a/MagicSDK.podspec b/MagicSDK.podspec index 11a5688..38e27f0 100644 --- a/MagicSDK.podspec +++ b/MagicSDK.podspec @@ -3,7 +3,7 @@ # Pod::Spec.new do |s| s.name = 'MagicSDK' - s.version = '6.2.0' + s.version = '7.0.0' s.summary = 'Magic IOS SDK' s.description = <<-DESC diff --git a/Sources/MagicSDK/Core/Magic.swift b/Sources/MagicSDK/Core/Magic.swift index 56e6076..08e21fd 100644 --- a/Sources/MagicSDK/Core/Magic.swift +++ b/Sources/MagicSDK/Core/Magic.swift @@ -9,17 +9,18 @@ import MagicSDK_Web3 import WebKit -internal enum ProductType{ - case MA - case MC -} - /// An instance of the Magic SDK -public class Magic: MagicCore { - - // MARK: - Module +public class Magic: NSObject { + // MARK: - Log Message Warning + public let MA_EXTENSION_ONLY_MSG = "This extension only works with Magic Auth API Keys" + + // MARK: - Modules public let user: UserModule public let auth: AuthModule + public let wallet: WalletModule + + // MARK: - Property + public var rpcProvider: RpcProvider /// Shared instance of `Magic` public static var shared: Magic! @@ -30,60 +31,29 @@ public class Magic: MagicCore { /// /// - Parameters: /// - apiKey: Your client ID. From https://dashboard.Magic.com - /// - ethNetwork: Network setting - public convenience init(apiKey: String, network: EthNetwork, locale: String = Locale.current.identifier) { - self.init(urlBuilder: URLBuilder(apiKey: apiKey, locale: locale, productType: .MA)) + /// - ethNetwork: Etherum Network setting (ie. mainnet or goerli) + /// - customNode: A custom RPC node + public convenience init(apiKey: String, ethNetwork: EthNetwork, locale: String = Locale.current.identifier) { + self.init(urlBuilder: URLBuilder(apiKey: apiKey, network: ethNetwork, locale: locale)) } public convenience init(apiKey: String, customNode: CustomNodeConfiguration, locale: String = Locale.current.identifier) { - let urlBuilder = URLBuilder(apiKey: apiKey, customNode: customNode, locale: locale, productType: ProductType.MA) - self.init(urlBuilder: urlBuilder) + self.init(urlBuilder: URLBuilder(apiKey: apiKey, customNode: customNode, locale: locale)) } public convenience init(apiKey: String, locale: String = Locale.current.identifier) { - self.init(urlBuilder: URLBuilder(apiKey: apiKey, locale: locale, productType: .MA)) + self.init(urlBuilder: URLBuilder(apiKey: apiKey, network: EthNetwork.mainnet, locale: locale)) } /// Core constructor private init(urlBuilder: URLBuilder) { - let rpcProvider = RpcProvider(urlBuilder: urlBuilder) - self.user = UserModule(rpcProvider: rpcProvider) - self.auth = AuthModule(rpcProvider: rpcProvider) - super.init(rpcProvider: rpcProvider) - } -} - -/// An instance of the Magic SDK -public class MagicConnect: MagicCore { - - public let connect: ConnectModule - - /// Shared instance of `Magic` - public static var shared: MagicConnect! - - public convenience init(apiKey: String) { - let urlBuilder = URLBuilder(apiKey: apiKey, ethNetwork: EthNetwork.mainnet, locale: "en_US", productType: ProductType.MC) - self.init(urlBuilder: urlBuilder) - } - - public convenience init(apiKey: String, network: EthNetwork) { - let urlBuilder = URLBuilder(apiKey: apiKey, ethNetwork: network, locale: "en_US", productType: ProductType.MC) - self.init(urlBuilder: urlBuilder) - } - - private init(urlBuilder: URLBuilder) { - let rpcProvider = RpcProvider(urlBuilder: urlBuilder) - self.connect = ConnectModule(rpcProvider: rpcProvider) - super.init(rpcProvider: rpcProvider) - } -} - -public class MagicCore: NSObject { - - public var rpcProvider: RpcProvider - - internal init(rpcProvider: RpcProvider) { - self.rpcProvider = rpcProvider + self.rpcProvider = RpcProvider(urlBuilder: urlBuilder) + + self.user = UserModule(rpcProvider: self.rpcProvider) + self.auth = AuthModule(rpcProvider: self.rpcProvider) + self.wallet = WalletModule(rpcProvider: self.rpcProvider) + + super.init() } } diff --git a/Sources/MagicSDK/Core/Relayer/URLBuilder.swift b/Sources/MagicSDK/Core/Relayer/URLBuilder.swift index 19c0e72..658d302 100644 --- a/Sources/MagicSDK/Core/Relayer/URLBuilder.swift +++ b/Sources/MagicSDK/Core/Relayer/URLBuilder.swift @@ -15,60 +15,73 @@ import Foundation public struct URLBuilder { let encodedParams, url: String + static let host = "https://box.magic.link" - public let apiKey: String - init(apiKey: String, customNode: CustomNodeConfiguration? = nil, ethNetwork: EthNetwork? = nil, locale: String, productType: ProductType) { + init(apiKey: String, customNode: CustomNodeConfiguration? = nil, network: EthNetwork? = nil, locale: String) { + + let data = try! JSONEncoder().encode( + UrlParamsEncodable( + apiKey: apiKey, + ethNetwork: network, + customNode: customNode, + locale: locale + ) + ) - let data = try! JSONEncoder().encode(paramsEncodable(apiKey: apiKey, ethNetwork: ethNetwork, customNode: customNode, locale: locale, productType: productType)) - self.init(data: data, host: URLBuilder.host, apiKey: apiKey, productType: productType) + self.init(data: data, host: URLBuilder.host, apiKey: apiKey) } - private init(data: Data, host: String, apiKey: String, productType: ProductType) { + private init(data: Data, host: String, apiKey: String) { + let jsonString = String(data: data, encoding: .utf8)! - let string = jsonString.replacingOccurrences(of: "\\", with: "") + let sanitizedJsonString = jsonString.replacingOccurrences(of: "\\", with: "") + // Encode instantiate option to params self.apiKey = apiKey - self.encodedParams = btoa(jsonString: string) + self.encodedParams = btoa(jsonString: sanitizedJsonString) + self.url = "\(host)/send/?params=\(self.encodedParams)" } - // MARK: - Options structs - struct paramsEncodable: Encodable { - let API_KEY: String + // MARK: - UrlParamsEncodable + struct UrlParamsEncodable: Encodable { + + let apiKey: String let locale: String let customNode: CustomNodeConfiguration? let ethNetwork: EthNetwork? - let productType: ProductType - init(apiKey: String, ethNetwork: EthNetwork?, customNode: CustomNodeConfiguration?, locale: String, productType: ProductType) { - self.productType = productType + + init(apiKey: String, ethNetwork: EthNetwork?, customNode: CustomNodeConfiguration?, locale: String) { + self.apiKey = apiKey + self.locale = locale self.customNode = customNode self.ethNetwork = ethNetwork - self.API_KEY = apiKey - self.locale = locale } enum CodingKeys: String, CodingKey { - case sdk, bundleId, API_KEY, host, ETH_NETWORK, ext + case apiKey = "API_KEY" + case ethNetwork = "ETH_NETWORK" + case bundleId, host, sdk } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode("magic-sdk-ios", forKey: .sdk) try container.encode(Bundle.main.bundleIdentifier, forKey: .bundleId) - try container.encode(self.API_KEY, forKey: .API_KEY) + + try container.encode(apiKey, forKey: .apiKey) try container.encode(URLBuilder.host, forKey: .host) - /// Network - if (customNode != nil) { - try container.encode(customNode, forKey: .ETH_NETWORK) + + if let node = customNode { + try container.encode(node, forKey: .ethNetwork) } - if (ethNetwork != nil) { - try container.encode(ethNetwork?.rawValue, forKey: .ETH_NETWORK) + if let network = ethNetwork { + try container.encode(network.rawValue, forKey: .ethNetwork) } - - try container.encode(ExtensionObject(productType: productType), forKey: .ext) } } } @@ -83,35 +96,3 @@ public struct CustomNodeConfiguration: Encodable { self.chainId = chainId } } - - -// MARK: -- Extension -struct ExtensionObject: Encodable { - - let productType: ProductType - - init(productType: ProductType) { - self.productType = productType - } - - enum CodingKeys: String, CodingKey { - case connect - } - - func encode(to encoder: Encoder) throws { - var container = encoder.container(keyedBy: CodingKeys.self) - - switch productType { - case .MC: - try container.encode(MCConfig(), forKey: .connect) - break - default: - break - } - - } -} - -internal struct MCConfig: Encodable { - let mc = true -} diff --git a/Sources/MagicSDK/Modules/Auth/AuthModule.swift b/Sources/MagicSDK/Modules/Auth/AuthModule.swift index ffd85f6..6f4108d 100644 --- a/Sources/MagicSDK/Modules/Auth/AuthModule.swift +++ b/Sources/MagicSDK/Modules/Auth/AuthModule.swift @@ -9,8 +9,14 @@ import Foundation import MagicSDK_Web3 import PromiseKit +import os public class AuthModule: BaseModule { + @available(iOS 14.0, *) + private static let logger = Logger( + subsystem: Bundle.main.bundleIdentifier!, + category: String(describing: AuthModule.self) + ) // MARK: - Login with magic link public func loginWithMagicLink (_ configuration: LoginWithMagicLinkConfiguration, response: @escaping Web3ResponseCompletion ) { @@ -32,6 +38,11 @@ public class AuthModule: BaseModule { // MARK: - Login with SMS public func loginWithSMS (_ configuration: LoginWithSmsConfiguration, response: @escaping Web3ResponseCompletion ) { + if #available(iOS 14.0, *) { + AuthModule.logger.warning("loginWithSMS: \(BaseWarningLog.MA_Method)") + } else { + print("loginWithSMS: \(BaseWarningLog.MA_Method)") + } let request = RPCRequest<[LoginWithSmsConfiguration]>(method: AuthMethod.magic_auth_login_with_sms.rawValue, params: [configuration]) self.provider.send(request: request, response: response) } @@ -44,6 +55,12 @@ public class AuthModule: BaseModule { // MARK: - Login with EmailOTP public func loginWithEmailOTP (_ configuration: LoginWithEmailOTPConfiguration, response: @escaping Web3ResponseCompletion ) { + if #available(iOS 14.0, *) { + AuthModule.logger.warning("loginWithEmailOTP: \(BaseWarningLog.MA_Method)") + } else { + print("loginWithEmailOTP: \(BaseWarningLog.MA_Method)") + } + let request = RPCRequest<[LoginWithEmailOTPConfiguration]>(method: AuthMethod.magic_auth_login_with_email_otp.rawValue, params: [configuration]) self.provider.send(request: request, response: response) } diff --git a/Sources/MagicSDK/Modules/BaseWarningLog.swift b/Sources/MagicSDK/Modules/BaseWarningLog.swift new file mode 100644 index 0000000..f24fbed --- /dev/null +++ b/Sources/MagicSDK/Modules/BaseWarningLog.swift @@ -0,0 +1,13 @@ +// +// BaseWarningLog.swift +// +// +// Created by Arian Flores - Magic on 2/16/23. +// + +import Foundation + +struct BaseWarningLog { + static let MA_Method = "This method only works with Magic Auth API Keys" + static let MC_Method = "This method only works with Magic Connect API Keys" +} diff --git a/Sources/MagicSDK/Modules/Connect/ConnectConfiguration.swift b/Sources/MagicSDK/Modules/Connect/ConnectConfiguration.swift deleted file mode 100644 index 804f957..0000000 --- a/Sources/MagicSDK/Modules/Connect/ConnectConfiguration.swift +++ /dev/null @@ -1,18 +0,0 @@ -// -// ConnectConfiguration.swift -// -// -// Created by Jerry Liu on 9/16/22. -// - -import Foundation - -public struct RequestUserInfoConfiguration: BaseConfiguration { - - /// - public var isResponseRequired = false - - public init(isResponseRequired: Bool = false) { - self.isResponseRequired = isResponseRequired - } -} diff --git a/Sources/MagicSDK/Modules/Connect/ConnectModule.swift b/Sources/MagicSDK/Modules/Connect/ConnectModule.swift deleted file mode 100644 index 5f65b27..0000000 --- a/Sources/MagicSDK/Modules/Connect/ConnectModule.swift +++ /dev/null @@ -1,53 +0,0 @@ -// -// ConnectModule.swift -// -// -// Created by Jerry Liu on 9/6/22. -// - -import Foundation -import MagicSDK_Web3 - -public class ConnectModule: BaseModule { - - /** - getWalletInfo - */ - public func getWalletInfo(response: @escaping Web3ResponseCompletion) { - - let request = BasicRPCRequest(method: ConnectMethod.mc_get_wallet_info.rawValue, params: []) - - return self.provider.send(request: request, response: response) - } - - - /** - showWallet - */ - public func showWallet(response: @escaping Web3ResponseCompletion) { - - let request = BasicRPCRequest(method: ConnectMethod.mc_wallet.rawValue, params: []) - - return self.provider.send(request: request, response: response) - } - - /** - requestUserInfo - */ - public func requestUserInfo(_ configuration: RequestUserInfoConfiguration = RequestUserInfoConfiguration(), response: @escaping Web3ResponseCompletion) { - - let request = RPCRequest<[RequestUserInfoConfiguration]>(method: ConnectMethod.mc_request_user_info.rawValue, params: [configuration]) - - return self.provider.send(request: request, response: response) - } - - /** - disconnect - */ - public func disconnect(response: @escaping Web3ResponseCompletion) { - - let request = BasicRPCRequest(method: ConnectMethod.mc_disconnect.rawValue, params: []) - - return self.provider.send(request: request, response: response) - } -} diff --git a/Sources/MagicSDK/Modules/User/UserModule.swift b/Sources/MagicSDK/Modules/User/UserModule.swift index bdfd1fb..7f222a7 100644 --- a/Sources/MagicSDK/Modules/User/UserModule.swift +++ b/Sources/MagicSDK/Modules/User/UserModule.swift @@ -8,13 +8,23 @@ import Foundation import MagicSDK_Web3 import PromiseKit +import os public class UserModule: BaseModule { - + @available(iOS 14.0, *) + private static let logger = Logger( + subsystem: Bundle.main.bundleIdentifier!, + category: String(describing: UserModule.self) + ) /** GetIdToken */ public func getIdToken(_ configuration: GetIdTokenConfiguration? = nil, response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + UserModule.logger.warning("getIdToken: \(BaseWarningLog.MA_Method)") + } else { + print("getIdToken: \(BaseWarningLog.MA_Method)") + } let request = RPCRequest<[GetIdTokenConfiguration?]>(method: UserMethod.magic_auth_get_id_token.rawValue, params: [configuration]) @@ -31,6 +41,11 @@ public class UserModule: BaseModule { Generate Id Token */ public func generateIdToken(_ configuration: GenerateIdTokenConfiguration? = nil, response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + UserModule.logger.warning("generateIdToken: \(BaseWarningLog.MA_Method)") + } else { + print("generateIdToken: \(BaseWarningLog.MA_Method)") + } let request = RPCRequest<[GenerateIdTokenConfiguration?]>(method: UserMethod.magic_auth_generate_id_token.rawValue, params: [configuration]) @@ -48,6 +63,12 @@ public class UserModule: BaseModule { Get Metadata */ public func getMetadata(response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + UserModule.logger.warning("getMetadata: \(BaseWarningLog.MA_Method)") + } else { + print("getMetadata: \(BaseWarningLog.MA_Method)") + } + let request = BasicRPCRequest(method: UserMethod.magic_auth_get_metadata.rawValue, params: []) return self.provider.send(request: request, response: response) } @@ -62,6 +83,11 @@ public class UserModule: BaseModule { IsLogged In */ public func isLoggedIn(response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + UserModule.logger.warning("isLoggedIn: \(BaseWarningLog.MA_Method)") + } else { + print("isLoggedIn: \(BaseWarningLog.MA_Method)") + } let request = BasicRPCRequest(method: UserMethod.magic_auth_is_logged_in.rawValue, params: []) self.provider.send(request: request, response: response) } @@ -76,7 +102,6 @@ public class UserModule: BaseModule { * Update Email */ public func updateEmail(_ configuration: UpdateEmailConfiguration, response: @escaping Web3ResponseCompletion) { - let request = RPCRequest<[UpdateEmailConfiguration]>(method: UserMethod.magic_auth_update_email.rawValue, params: [configuration]) return self.provider.send(request: request, response: response) @@ -98,6 +123,12 @@ public class UserModule: BaseModule { Logout */ public func logout (response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + UserModule.logger.warning("logout: \(BaseWarningLog.MA_Method)") + } else { + print("logout: \(BaseWarningLog.MA_Method)") + } + let request = BasicRPCRequest(method: UserMethod.magic_auth_logout.rawValue, params: []) self.provider.send(request: request, response: response) } @@ -111,6 +142,12 @@ public class UserModule: BaseModule { showSettings */ public func showSettings(response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + UserModule.logger.warning("showSettings: \(BaseWarningLog.MA_Method)") + } else { + print("showSettings: \(BaseWarningLog.MA_Method)") + } + let request = BasicRPCRequest(method: UserMethod.magic_auth_settings.rawValue, params: []) self.provider.send(request: request, response: response) } @@ -139,6 +176,11 @@ public class UserModule: BaseModule { recoverAccount */ public func recoverAccount(_ configuration: RecoverAccountConfiguration, response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + UserModule.logger.warning("recoverAccount: \(BaseWarningLog.MA_Method)") + } else { + print("recoverAccount: \(BaseWarningLog.MA_Method)") + } let request = RPCRequest<[RecoverAccountConfiguration]>(method: UserMethod.magic_auth_recover_account.rawValue, params: [configuration]) diff --git a/Sources/MagicSDK/Modules/Wallet/WalletConfiguration.swift b/Sources/MagicSDK/Modules/Wallet/WalletConfiguration.swift new file mode 100644 index 0000000..bf85b42 --- /dev/null +++ b/Sources/MagicSDK/Modules/Wallet/WalletConfiguration.swift @@ -0,0 +1,32 @@ +// +// WalletConfiguration.swift +// +// +// Created by Arian Flores on 02/16/23. +// + +import Foundation + +public enum WalletUserInfoEmailOptions: String, Codable { + case required, optional +} + +public struct RequestUserInfoWithUIConfiguration: BaseConfiguration { + let scope: WalletUserInfoScope + + public init(scope: WalletUserInfoScope) { + self.scope = scope + } + + enum CodingKeys: String, CodingKey { + case scope + } +} + +public struct WalletUserInfoScope: Codable { + var email: WalletUserInfoEmailOptions + + enum CodingKeys: String, CodingKey { + case email + } +} diff --git a/Sources/MagicSDK/Modules/Connect/ConnectMethod.swift b/Sources/MagicSDK/Modules/Wallet/WalletMethod.swift similarity index 68% rename from Sources/MagicSDK/Modules/Connect/ConnectMethod.swift rename to Sources/MagicSDK/Modules/Wallet/WalletMethod.swift index db03efd..6d5ebfa 100644 --- a/Sources/MagicSDK/Modules/Connect/ConnectMethod.swift +++ b/Sources/MagicSDK/Modules/Wallet/WalletMethod.swift @@ -7,9 +7,10 @@ import Foundation -internal enum ConnectMethod: String, CaseIterable { +internal enum WalletMethod: String, CaseIterable { // MC + case mc_login = "eth_requestAccounts" case mc_get_wallet_info case mc_wallet case mc_request_user_info diff --git a/Sources/MagicSDK/Modules/Wallet/WalletModule.swift b/Sources/MagicSDK/Modules/Wallet/WalletModule.swift new file mode 100644 index 0000000..bb948b1 --- /dev/null +++ b/Sources/MagicSDK/Modules/Wallet/WalletModule.swift @@ -0,0 +1,95 @@ +// +// WalletModule.swift +// +// +// Created by Arian Flores on 02/16/23. +// + +import Foundation +import MagicSDK_Web3 +import os + +public class WalletModule: BaseModule { + @available(iOS 14.0, *) + private static let logger = Logger( + subsystem: Bundle.main.bundleIdentifier!, + category: String(describing: WalletModule.self) + ) + + + /** + connectWithUI + */ + public func connectWithUI(response: @escaping Web3ResponseCompletion<[String]>) { + if #available(iOS 14.0, *) { + WalletModule.logger.warning("connectWithUI: \(BaseWarningLog.MC_Method)") + } else { + print("connectWithUI: \(BaseWarningLog.MC_Method)") + } + + let request = BasicRPCRequest(method: WalletMethod.mc_login.rawValue, params: []) + + return self.provider.send(request: request, response: response) + } + + /** + showUI + */ + public func showUI(response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + WalletModule.logger.warning("showUI: \(BaseWarningLog.MC_Method)") + } else { + print("showUI: \(BaseWarningLog.MC_Method)") + } + + let request = BasicRPCRequest(method: WalletMethod.mc_wallet.rawValue, params: []) + + return self.provider.send(request: request, response: response) + } + + /** + getInfo + */ + public func getInfo(response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + WalletModule.logger.warning("getInfo: \(BaseWarningLog.MC_Method)") + } else { + print("getInfo: \(BaseWarningLog.MC_Method)") + } + + let request = BasicRPCRequest(method: WalletMethod.mc_get_wallet_info.rawValue, params: []) + + return self.provider.send(request: request, response: response) + } + + + /** + requestUserInfoWithUI + */ + public func requestUserInfoWithUI(_ configuration: RequestUserInfoWithUIConfiguration? = nil, response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + WalletModule.logger.warning("requestUserInfoWithUI: \(BaseWarningLog.MC_Method)") + } else { + print("requestUserInfoWithUI: \(BaseWarningLog.MC_Method)") + } + + let request = RPCRequest<[RequestUserInfoWithUIConfiguration?]>(method: WalletMethod.mc_request_user_info.rawValue, params: (configuration != nil) ? [configuration]: []) + + return self.provider.send(request: request, response: response) + } + + /** + disconnect + */ + public func disconnect(response: @escaping Web3ResponseCompletion) { + if #available(iOS 14.0, *) { + WalletModule.logger.warning("disconnect: \(BaseWarningLog.MC_Method)") + } else { + print("disconnect: \(BaseWarningLog.MC_Method)") + } + + let request = BasicRPCRequest(method: WalletMethod.mc_disconnect.rawValue, params: []) + + return self.provider.send(request: request, response: response) + } +} diff --git a/Sources/MagicSDK/Modules/Connect/ConnectResponse.swift b/Sources/MagicSDK/Modules/Wallet/WalletResponse.swift similarity index 100% rename from Sources/MagicSDK/Modules/Connect/ConnectResponse.swift rename to Sources/MagicSDK/Modules/Wallet/WalletResponse.swift