Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit eb9b401

Browse files
authored
Merge pull request #1 from magiclabs/feat/migration
Migrate from fortmatic org to magic org
2 parents 8a75205 + fe1356a commit eb9b401

31 files changed

+1989
-9
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
/*.xcodeproj
5+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
6+
17
# Xcode
28
#
39
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

LICENSE

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
MIT License
2-
3-
Copyright (c) 2022 Magic
1+
Copyright (c) 2022 Magic Labs Inc. <support@magic.link>
42

53
Permission is hereby granted, free of charge, to any person obtaining a copy
64
of this software and associated documentation files (the "Software"), to deal
@@ -9,13 +7,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
97
copies of the Software, and to permit persons to whom the Software is
108
furnished to do so, subject to the following conditions:
119

12-
The above copyright notice and this permission notice shall be included in all
13-
copies or substantial portions of the Software.
10+
The above copyright notice and this permission notice shall be included in
11+
all copies or substantial portions of the Software.
1412

1513
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1614
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1715
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1816
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1917
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21-
SOFTWARE.
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.

MagicSDK.podspec

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#
2+
# Podspec for Cocoapod
3+
#
4+
Pod::Spec.new do |s|
5+
s.name = 'MagicSDK'
6+
s.version = '3.0.0'
7+
s.summary = 'Magic IOS SDK'
8+
9+
s.description = <<-DESC
10+
TODO: Add long description of the pod here.
11+
DESC
12+
13+
s.homepage = 'https://github.com/magiclabs/magic-ios'
14+
s.license = { :type => 'MIT', :file => 'LICENSE' }
15+
s.author = { 'Jerry Liu' => 'jerry@magic.link' }
16+
s.source = { :git => 'https://github.com/magiclabs/magic-ios.git', :tag => s.version.to_s }
17+
s.swift_version = '5.0'
18+
s.ios.deployment_target = '10.0'
19+
s.osx.deployment_target = '10.12'
20+
21+
s.source_files = 'Sources/MagicSDK/**/*'
22+
23+
s.dependency 'MagicSDK-Web3', '~> 1.0'
24+
s.dependency 'MagicSDK-Web3/ContractABI', '~> 1.0'
25+
s.dependency 'MagicSDK-Web3/PromiseKit', '~> 1.0'
26+
27+
s.dependency 'PromiseKit/CorePromise', '~> 6.15'
28+
29+
s.pod_target_xcconfig = { 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64' }
30+
end

Package.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// swift-tools-version:5.5
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "MagicSDK",
8+
platforms: [
9+
.iOS(.v10),
10+
.macOS(.v10_12)
11+
],
12+
products: [
13+
// Products define the executables and libraries a package produces, and make them visible to other packages.
14+
.library(
15+
name: "MagicSDK",
16+
targets: ["MagicSDK"]),
17+
],
18+
dependencies: [
19+
.package(url: "https://github.com/magiclabs/Web3.swift.git", from:"1.1.0"),
20+
.package(url: "https://github.com/mxcl/PromiseKit.git", from:"6.16.2")
21+
],
22+
targets: [
23+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
24+
// Targets can depend on other targets in this package, and on products in packages this package depends on.
25+
.target(
26+
name: "MagicSDK",
27+
dependencies: [
28+
.product(name: "MagicSDK_Web3", package: "Web3.swift"),
29+
.product(name: "Web3PromiseKit", package: "Web3.swift"),
30+
.product(name: "PromiseKit", package: "PromiseKit"),
31+
.product(name: "Web3ContractABI", package: "Web3.swift")
32+
]),
33+
.testTarget(
34+
name: "MagicSDKTests",
35+
dependencies: [
36+
.target(name: "MagicSDK")
37+
]),
38+
]
39+
)

README.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,41 @@
1-
# magic-ios
2-
MagicSDK library for IOS
1+
# MagicSDK
2+
[![CI Status](https://img.shields.io/travis/Ethella/MagicSDK.svg?style=flat)](https://travis-ci.org/Ethella/MagicSDK)
3+
[![Version](https://img.shields.io/cocoapods/v/MagicSDK.svg?style=flat)](https://cocoapods.org/pods/MagicSDK)
4+
[![License](https://img.shields.io/cocoapods/l/MagicSDK.svg?style=flat)](https://cocoapods.org/pods/MagicSDK)
5+
[![Platform](https://img.shields.io/cocoapods/p/MagicSDK.svg?style=flat)](https://cocoapods.org/pods/MagicSDK)
6+
7+
Cocoapods
8+
---
9+
## Set up the local development env
10+
1. To start the demo app with local development SDK, download following projects
11+
```bash
12+
# demo app
13+
$ git clone https://github.com/magiclabs/magic-ios-demo
14+
# ios SDK
15+
$ git clone https://github.com/magiclabs/magic-ios
16+
```
17+
18+
2. To enable the demo use the local development SDK. Navigate to `magic-ios-demo/Podfile` and edit the following lines.
19+
This will make pod file install local dependencies instead of the ones distributed.
20+
21+
```ruby
22+
# Distributed Library on Cocoapods
23+
# pod 'MagicSDK', '~> 3.0'
24+
# pod 'MagicExt-OAuth', '~> 0.8'
25+
26+
# Local development library
27+
pod 'MagicSDK', :path => '../magic-ios/MagicSDK.podspec'
28+
pod 'MagicExt-OAuth', :path => '../magic-ios-ext/MagicExt-OAuth.podspec'
29+
```
30+
31+
```bash
32+
$ cd /YOUR/PATH/TO/magic-ios-demo
33+
34+
# Install dependencies
35+
$ pod install
36+
```
37+
38+
3. Open `/YOUR/PATH/TO/magic-ios-demo/magic-ios-demo.xcworkspace` with XCode and try it out!
39+
40+
---
41+

Sources/MagicSDK/Core/Magic.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// Magic.swift
3+
// Magic ios SDK
4+
//
5+
// Created by Jerry Liu on 1/20/20.
6+
// Copyright © 2020 Magic Labs Inc. All rights reserved.
7+
//
8+
import MagicSDK_Web3
9+
import WebKit
10+
11+
/// An instance of the Magic SDK
12+
public class Magic: NSObject {
13+
14+
// MARK: - Module
15+
public let user: UserModule
16+
public let auth: AuthModule
17+
18+
// MARK: - Property
19+
private let overlay: WebViewController
20+
public var rpcProvider: RpcProvider
21+
22+
/// Shared instance of `Magic`
23+
public static var shared: Magic!
24+
25+
// MARK: - Initialization
26+
27+
/// Initialize an instance of `Magic`
28+
///
29+
/// - Parameters:
30+
/// - apiKey: Your client ID. From https://dashboard.Magic.com
31+
/// - ethNetwork: Network setting
32+
public convenience init(apiKey: String, network: EthNetwork, locale: String = Locale.current.identifier) {
33+
self.init(urlBuilder: URLBuilder(apiKey: apiKey, network: EthNetworkConfiguration(network: network), locale: locale))
34+
}
35+
36+
public convenience init(apiKey: String, customNode: CustomNodeConfiguration, locale: String = Locale.current.identifier) {
37+
self.init(urlBuilder: URLBuilder(apiKey: apiKey, customNode: customNode, locale: locale))
38+
}
39+
40+
public convenience init(apiKey: String, locale: String = Locale.current.identifier) {
41+
self.init(urlBuilder: URLBuilder(apiKey: apiKey, network: EthNetworkConfiguration(network: apiKey.contains("live") ? EthNetwork.mainnet: EthNetwork.rinkeby), locale: locale))
42+
}
43+
44+
private init(urlBuilder: URLBuilder) {
45+
self.overlay = WebViewController(url: urlBuilder)
46+
self.rpcProvider = RpcProvider(overlay: self.overlay, urlBuilder: urlBuilder)
47+
self.user = UserModule(rpcProvider: self.rpcProvider)
48+
self.auth = AuthModule(rpcProvider: self.rpcProvider)
49+
super.init()
50+
}
51+
}
52+
53+
// Handles Specific RpcError
54+
extension Web3Response {
55+
public var magicAuthError: RpcProvider.ProviderError? {
56+
switch self.status {
57+
case .failure(let error):
58+
return error as? RpcProvider.ProviderError
59+
case .success:
60+
return nil
61+
@unknown default:
62+
return nil
63+
}
64+
}
65+
}
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//
2+
// NetworkClient.swift
3+
// Magic
4+
//
5+
// Created by Jerry Liu on 2/09/20.
6+
// Copyright © 2020 Magic Labs Inc. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import PromiseKit
11+
12+
/// A base networking class that can send http requests
13+
public class NetworkClient {
14+
15+
/// Various errors that may occur while processing Web3 requests
16+
public enum Error: Swift.Error {
17+
/// The response did not include expected results
18+
case unexpectedResponse(Swift.Error?)
19+
/// The server returned an unexpected response code
20+
case invalidResponseCode
21+
}
22+
23+
/// Internal queue for handling requests
24+
let queue: DispatchQueue
25+
26+
/// Internal URLSession for this Web3Provider's RPC requests
27+
let session: URLSession = URLSession(configuration: .default)
28+
29+
/// JSONEncoder for encoding RPCRequests
30+
let encoder = JSONEncoder()
31+
32+
/// JSONDecoder for parsing RPCResponses
33+
let decoder = JSONDecoder()
34+
35+
/// HTTP headers to add to all requests
36+
public var headers = [
37+
"Content-Type": "application/json"
38+
]
39+
40+
init() {
41+
self.queue = DispatchQueue(label: "MagicHttpProvider", attributes: .concurrent)
42+
}
43+
44+
/// Encode an object with or without a prefix into data
45+
///
46+
/// - Parameters:
47+
/// - body: Object to encode. Must be Encodable.
48+
/// - prefix: Optional string to prefix the body with
49+
/// - Returns: Promise resolving with the encoded Data
50+
func encode<T: Encodable>(body: T, withPrefix prefix: String? = nil) -> Promise<Data> {
51+
return Promise { resolver in
52+
queue.async {
53+
do {
54+
let encoded: Data
55+
if let prefix = prefix {
56+
encoded = try self.encoder.encode([prefix: body])
57+
} else {
58+
encoded = try self.encoder.encode(body)
59+
}
60+
resolver.fulfill(encoded)
61+
} catch {
62+
resolver.reject(error)
63+
}
64+
}
65+
}
66+
}
67+
68+
/// Sends a basic http request.
69+
/// This method will create a URLRequest, and then run a URLSessionDataTask with the URLRequest.
70+
/// Once a response is received, the response will be validated for data and a valid status code
71+
/// before calling the callback with the resulting data or error.
72+
///
73+
/// - Parameters:
74+
/// - url: url for the request
75+
/// - method: HTTP method to use
76+
/// - body: Optional request body to include
77+
/// - Returns: Promise resolving with Data from the response if it's successful
78+
func postRequest(url: URL, method: String, body: Data?) -> Promise<Data> {
79+
return Promise { resolver in
80+
queue.async {
81+
var req = URLRequest(url: url)
82+
req.httpMethod = method
83+
req.httpBody = body
84+
85+
// Add default headers
86+
for (k, v) in self.headers {
87+
req.addValue(v, forHTTPHeaderField: k)
88+
}
89+
90+
// Create the URLSessionTask
91+
let task = self.session.dataTask(with: req) { data, urlResponse, error in
92+
guard let urlResponse = urlResponse as? HTTPURLResponse, let data = data, error == nil else {
93+
resolver.reject(Error.unexpectedResponse(error))
94+
return
95+
}
96+
97+
guard urlResponse.statusCode >= 200 && urlResponse.statusCode < 300 else {
98+
resolver.reject(Error.invalidResponseCode)
99+
return
100+
}
101+
102+
resolver.fulfill(data)
103+
}
104+
task.resume()
105+
}
106+
}
107+
}
108+
109+
}

0 commit comments

Comments
 (0)