├── .gitignore
├── .swift-version
├── Example
├── Podfile
├── Podfile.lock
├── Tests
│ ├── Info.plist
│ ├── WCBinanceTradePairTests.swift
│ ├── WCEncryptorTests.swift
│ └── WCSessionTests.swift
├── WalletConnect.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── WalletConnect-Example.xcscheme
├── WalletConnect.xcworkspace
│ └── contents.xcworkspacedata
└── WalletConnect
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
│ ├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ └── ViewController.swift
├── LICENSE
├── README.md
├── WalletConnect.podspec
├── WalletConnect
├── Assets
│ └── .gitkeep
├── Extensions
│ ├── Data+Hex.swift
│ └── Encodable+Extension.swift
├── JSONRPC
│ └── JSONRPC.swift
├── Models
│ ├── Binance
│ │ ├── WCBinanceCancelOrder.swift
│ │ ├── WCBinanceOrder.swift
│ │ ├── WCBinanceTradeOrder.swift
│ │ ├── WCBinanceTradePair.swift
│ │ └── WCBinanceTransferOrder.swift
│ ├── Ethereum
│ │ └── WCEthereumSendTransaction.swift
│ ├── WCEvent.swift
│ ├── WCPeerMeta.swift
│ ├── WCSessionModels.swift
│ └── WCSocketMessage.swift
├── WCEncryptor.swift
├── WCError.swift
├── WCInteractor.swift
└── WCSession.swift
└── _Pods.xcodeproj
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Ignore when build
10 | .DS_Store
11 |
12 | ## Various settings
13 | *.pbxuser
14 | !default.pbxuser
15 | *.mode1v3
16 | !default.mode1v3
17 | *.mode2v3
18 | !default.mode2v3
19 | *.perspectivev3
20 | !default.perspectivev3
21 | xcuserdata/
22 |
23 | ## Other
24 | *.moved-aside
25 | *.xccheckout
26 | *.xcscmblueprint
27 |
28 | ## Obj-C/Swift specific
29 | *.hmap
30 | *.ipa
31 | *.dSYM.zip
32 | *.dSYM
33 |
34 | ## Playgrounds
35 | timeline.xctimeline
36 | playground.xcworkspace
37 |
38 | # Swift Package Manager
39 | #
40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
41 | # Packages/
42 | # Package.pins
43 | # Package.resolved
44 | .build/
45 |
46 | # CocoaPods
47 | #
48 | # We recommend against adding the Pods directory to your .gitignore. However
49 | # you should judge for yourself, the pros and cons are mentioned at:
50 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
51 | #
52 | Pods/
53 |
54 | # Carthage
55 | #
56 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
57 | # Carthage/Checkouts
58 |
59 | Carthage/Build
60 |
61 | #R
62 | *.generated.swift
63 |
64 | *.mobileprovision
65 | *.cer
66 |
67 | # VIM
68 | *.swp
69 | *.swo
70 | *~
71 | *.orig
72 |
73 | # node
74 | node_modules
75 | JS/staging
76 |
--------------------------------------------------------------------------------
/.swift-version:
--------------------------------------------------------------------------------
1 | 4.2
2 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, '11.0'
2 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
3 | inhibit_all_warnings!
4 | use_frameworks!
5 |
6 | target 'WalletConnect_Example' do
7 | pod 'WalletConnect', :path => '../'
8 | pod 'TrustWalletCore'
9 | target 'WalletConnect_Tests' do
10 | inherit! :search_paths
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - CryptoSwift (1.0.0)
3 | - PromiseKit (6.8.3):
4 | - PromiseKit/CorePromise (= 6.8.3)
5 | - PromiseKit/Foundation (= 6.8.3)
6 | - PromiseKit/UIKit (= 6.8.3)
7 | - PromiseKit/CorePromise (6.8.3)
8 | - PromiseKit/Foundation (6.8.3):
9 | - PromiseKit/CorePromise
10 | - PromiseKit/UIKit (6.8.3):
11 | - PromiseKit/CorePromise
12 | - Starscream (3.1.0)
13 | - SwiftProtobuf (1.3.1)
14 | - TrustWalletCore (0.9.0):
15 | - SwiftProtobuf (~> 1.3.0)
16 | - WalletConnect (0.1.0):
17 | - CryptoSwift
18 | - PromiseKit
19 | - Starscream
20 |
21 | DEPENDENCIES:
22 | - TrustWalletCore
23 | - WalletConnect (from `../`)
24 |
25 | SPEC REPOS:
26 | https://github.com/cocoapods/specs.git:
27 | - CryptoSwift
28 | - PromiseKit
29 | - Starscream
30 | - SwiftProtobuf
31 | - TrustWalletCore
32 |
33 | EXTERNAL SOURCES:
34 | WalletConnect:
35 | :path: "../"
36 |
37 | SPEC CHECKSUMS:
38 | CryptoSwift: d81eeaa59dc5a8d03720fe919a6fd07b51f7439f
39 | PromiseKit: 94c6e781838c5bf4717677d0d882b0e7250c80fc
40 | Starscream: 08172b481e145289c4930cb567230fb55897cfa4
41 | SwiftProtobuf: 84cd6b8f4fd2fc3d9fbd80a0aaf2e957d52824ec
42 | TrustWalletCore: c05884ebc535de50e1681c72bbaeaaf36b696280
43 | WalletConnect: 71cb5714f6ee438f28eb0aad35c147b47204bff9
44 |
45 | PODFILE CHECKSUM: a1e603c059b0895d70f3a913a20334918afd4244
46 |
47 | COCOAPODS: 1.6.1
48 |
--------------------------------------------------------------------------------
/Example/Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Example/Tests/WCBinanceTradePairTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCBinanceTradePairTests.swift
3 | // WalletConnect_Tests
4 | //
5 | // Created by Tao Xu on 4/18/19.
6 | // Copyright © 2019 CocoaPods. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import WalletConnect
11 |
12 | class WCBinanceTradePairTests: XCTestCase {
13 |
14 | func testParsing() {
15 | let symbol = "BNB_ETH.B-261"
16 | let pair = WCBinanceTradePair.from(symbol)
17 |
18 | XCTAssertEqual(pair?.from, "BNB")
19 | XCTAssertEqual(pair?.to, "ETH.B")
20 |
21 | let symbol2 = "000-0E1_BNB"
22 | let pair2 = WCBinanceTradePair.from(symbol2)
23 |
24 | XCTAssertEqual(pair2?.from, "000")
25 | XCTAssertEqual(pair2?.to, "BNB")
26 |
27 | let symbol3 = "CRYPRICE-150_BTC.B-918"
28 | let pair3 = WCBinanceTradePair.from(symbol3)
29 |
30 | XCTAssertEqual(pair3?.from, "CRYPRICE")
31 | XCTAssertEqual(pair3?.to, "BTC.B")
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Example/Tests/WCEncryptorTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCEncryptorTests.swift
3 | // WalletConnectTests
4 | //
5 | // Created by Tao Xu on 4/1/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import WalletConnect
11 |
12 | class WCEncryptorTests: XCTestCase {
13 | func testDecrypt() throws {
14 | let data = "1b3db3674de082d65455eba0ae61cfe7e681c8ef1132e60c8dbd8e52daf18f4fea42cc76366c83351dab6dca52682ff81f828753f89a21e1cc46587ca51ccd353914ffdd3b0394acfee392be6c22b3db9237d3f717a3777e3577dd70408c089a4c9c85130a68c43b0a8aadb00f1b8a8558798104e67aa4ff027b35d4b989e7fd3988d5dcdd563105767670be735b21c4"
15 | let hmac = "a33f868e793ca4fcca964bcb64430f65e2f1ca7a779febeaf94c5373d6df48b3"
16 | let iv = "89ef1d6728bac2f1dcde2ef9330d2bb8"
17 | let key = Data(hex: "5caa3a74154cee16bd1b570a1330be46e086474ac2f4720530662ef1a469662c")
18 | let payload = WCEncryptionPayload(data: data, hmac: hmac, iv: iv)
19 | let decrypted = try WCEncryptor.decrypt(payload: payload, with: key)
20 |
21 | let expect = """
22 | {"id":1554098597199736,"jsonrpc":"2.0","method":"wc_sessionUpdate","params":[{"approved":false,"chainId":null,"accounts":null}]}
23 | """
24 | XCTAssertEqual(expect, String(data: decrypted, encoding: .utf8)!)
25 | }
26 |
27 | func testDecryptRejectSession() throws {
28 | // wc:3c5318c3-fba2-4e57-bca3-854e7ac9c51e@1?bridge=https%3A%2F%2Fbridge.walletconnect.org&key=bbc82a01ebdb14698faee4a9e5038de72c995a9f6bcdb21903d62408b0c5ca96
29 | let data = "e7df9810ce66defcc03023ee945f5958c1d4697bf97945daeab5059c2bc6262642cbca82982ac690e77e16671770c200f348f743a7c6e5df5c74eb892ef9b45a9b5ddf0f08fa60c49e5b694688d1b0b521b43975e65b4e8d557a83f4d1aab0af"
30 | let hmac = "ffcf0f43aeb0ef36dd2ea641ab7f48b9abbf2d9f65354aefc7faf530d318a9fe"
31 | let iv = "debb62725b21c7577e4e498e10f096c7"
32 | let key = Data(hex: "bbc82a01ebdb14698faee4a9e5038de72c995a9f6bcdb21903d62408b0c5ca96")
33 | let payload = WCEncryptionPayload(data: data, hmac: hmac, iv: iv)
34 | let decrypted = try WCEncryptor.decrypt(payload: payload, with: key)
35 |
36 | let expect = """
37 | {"jsonrpc":"2.0","id":1554343834752446,"error":{"code":-32000,"message":"Session Rejected"}}
38 | """
39 | XCTAssertEqual(expect, String(data: decrypted, encoding: .utf8)!)
40 | }
41 |
42 | func testDecryptBnbSign() throws {
43 | // wc:e7f48633-b2d5-43de-ab0a-f83a451a079c@1?bridge=https%3A%2F%2Fwallet-bridge.fdgahl.cn&key=10b653558be908057c2584b93d27cb0a6d020aa4520af9fef036dd0fec324668
44 | let data = "9e3a3590371e27596745ac4665d4e50d148804413b7fc1ea2b7f4866562ce7c61d5cd21e7c442edd41f20de891a87988c89e28458cba5051aabd74cab0e700fffcd9a383e05292c2053eb256a4e98c435b72359e189f6a9374489a6e6aef6d8356d183cf358c81ce532a21dd27f594981ab0e1f1d8fb0545a4dc6fa626bc891590d4d673e7d876b7684913c9134fb52870c4beb057a55deb7c8e7b3d237ff4b41287744d8f41fa74ee253d0d1a7833965191172ae2cc814dda53e599eb4dbb41c1c60416c2385af38f0093a9dec97e4892a9f7793d24b43d087fa1ee549bc7037269cb19f68e32dae38ac695197c389c04fa043273f29abe0d0aee6933f237488361e0a4415e2e41541dd068304bd6051e099d3fbc909d9c237694c858080e461ceceabb3cb06048b5ac9b2944a28b7a516308f2e1ff9089bbcd3ead12066edcabc8fb8b28e40fa6ffb7943bfbb9fa8695324104798489724e1328d3000cb7bb0518f64117c5b871b282ac6bb3d1e213f4e82137402e6fd69478b145a5b5f059"
45 | let hmac = "d910de5672d1506129ad35709fa0d7c4618814605e8529385b089f899a99b574"
46 | let iv = "7cfdc41e3b2bee432a196770bb644865"
47 | let key = Data(hex: "10b653558be908057c2584b93d27cb0a6d020aa4520af9fef036dd0fec324668")
48 |
49 | let payload = WCEncryptionPayload(data: data, hmac: hmac, iv: iv)
50 | let decrypted = try WCEncryptor.decrypt(payload: payload, with: key)
51 | let request: JSONRPCRequest<[WCBinanceTradeOrder]> = try WCEvent.bnbSign.decode(decrypted)
52 | XCTAssertNotNil(request)
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Example/Tests/WCSessionTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCSessionTests.swift
3 | // WalletConnectTests
4 | //
5 | // Created by Tao Xu on 4/1/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | import WalletConnect
11 |
12 | class WCSessionTests: XCTestCase {
13 |
14 | func testParse() {
15 | let uri = "wc:217374f6-8735-472d-a743-23bd7d26d106@1?bridge=https%3A%2F%2Fbridge.walletconnect.org&key=d565a3e6cc792fa789bbea26b3f257fb436cfba2de48d2490b3e0248168d4b6b"
16 |
17 | let session = WCSession.from(string: uri)
18 |
19 | XCTAssertNotNil(session)
20 | XCTAssertEqual(session?.topic, "217374f6-8735-472d-a743-23bd7d26d106")
21 | XCTAssertEqual(session?.version, "1")
22 | XCTAssertEqual(session?.bridge.description, "https://bridge.walletconnect.org")
23 | XCTAssertEqual(session?.key, Data(hex: "d565a3e6cc792fa789bbea26b3f257fb436cfba2de48d2490b3e0248168d4b6b") )
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Example/WalletConnect.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5944A2D390134C9FF57ED3E8 /* Pods_WalletConnect_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E343012D932C98B685E7EFB2 /* Pods_WalletConnect_Tests.framework */; };
11 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
12 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
13 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
14 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
15 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
16 | 95B629BC9AE35AF7FECB685A /* Pods_WalletConnect_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58018BFAC1E050DECC1E3B9B /* Pods_WalletConnect_Example.framework */; };
17 | BB3C46572257496400966B16 /* WCEncryptorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3C46552257496400966B16 /* WCEncryptorTests.swift */; };
18 | BB3C46582257496400966B16 /* WCSessionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB3C46562257496400966B16 /* WCSessionTests.swift */; };
19 | BBFB765822681B18008CBC32 /* WCBinanceTradePairTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBFB765722681B18008CBC32 /* WCBinanceTradePairTests.swift */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXContainerItemProxy section */
23 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = {
24 | isa = PBXContainerItemProxy;
25 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */;
26 | proxyType = 1;
27 | remoteGlobalIDString = 607FACCF1AFB9204008FA782;
28 | remoteInfo = WalletConnect;
29 | };
30 | /* End PBXContainerItemProxy section */
31 |
32 | /* Begin PBXFileReference section */
33 | 3CAB43573298CF6540303C70 /* Pods-WalletConnect_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WalletConnect_Example.debug.xcconfig"; path = "Target Support Files/Pods-WalletConnect_Example/Pods-WalletConnect_Example.debug.xcconfig"; sourceTree = ""; };
34 | 58018BFAC1E050DECC1E3B9B /* Pods_WalletConnect_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WalletConnect_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
35 | 607FACD01AFB9204008FA782 /* WalletConnect_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WalletConnect_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
36 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
38 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
39 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
40 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
41 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
42 | 607FACE51AFB9204008FA782 /* WalletConnect_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = WalletConnect_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | 7B51907CCB4908B80495A7C7 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; };
45 | 898BD455BC548305184BF04B /* Pods-WalletConnect_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WalletConnect_Tests.release.xcconfig"; path = "Target Support Files/Pods-WalletConnect_Tests/Pods-WalletConnect_Tests.release.xcconfig"; sourceTree = ""; };
46 | 9FE02F50BAA093A28A16E601 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; };
47 | AF6FEF50E52A07BBD8821D45 /* Pods-WalletConnect_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WalletConnect_Tests.debug.xcconfig"; path = "Target Support Files/Pods-WalletConnect_Tests/Pods-WalletConnect_Tests.debug.xcconfig"; sourceTree = ""; };
48 | BB3C46552257496400966B16 /* WCEncryptorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WCEncryptorTests.swift; sourceTree = ""; };
49 | BB3C46562257496400966B16 /* WCSessionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WCSessionTests.swift; sourceTree = ""; };
50 | BBFB765722681B18008CBC32 /* WCBinanceTradePairTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WCBinanceTradePairTests.swift; sourceTree = ""; };
51 | C5AB14183732ECC55F0DC926 /* Pods-WalletConnect_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-WalletConnect_Example.release.xcconfig"; path = "Target Support Files/Pods-WalletConnect_Example/Pods-WalletConnect_Example.release.xcconfig"; sourceTree = ""; };
52 | E343012D932C98B685E7EFB2 /* Pods_WalletConnect_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_WalletConnect_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
53 | FF54DC7F0D5E8367EB168F5A /* WalletConnect.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = WalletConnect.podspec; path = ../WalletConnect.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
54 | /* End PBXFileReference section */
55 |
56 | /* Begin PBXFrameworksBuildPhase section */
57 | 607FACCD1AFB9204008FA782 /* Frameworks */ = {
58 | isa = PBXFrameworksBuildPhase;
59 | buildActionMask = 2147483647;
60 | files = (
61 | 95B629BC9AE35AF7FECB685A /* Pods_WalletConnect_Example.framework in Frameworks */,
62 | );
63 | runOnlyForDeploymentPostprocessing = 0;
64 | };
65 | 607FACE21AFB9204008FA782 /* Frameworks */ = {
66 | isa = PBXFrameworksBuildPhase;
67 | buildActionMask = 2147483647;
68 | files = (
69 | 5944A2D390134C9FF57ED3E8 /* Pods_WalletConnect_Tests.framework in Frameworks */,
70 | );
71 | runOnlyForDeploymentPostprocessing = 0;
72 | };
73 | /* End PBXFrameworksBuildPhase section */
74 |
75 | /* Begin PBXGroup section */
76 | 35A375D8C1409D77CED68BD2 /* Pods */ = {
77 | isa = PBXGroup;
78 | children = (
79 | 3CAB43573298CF6540303C70 /* Pods-WalletConnect_Example.debug.xcconfig */,
80 | C5AB14183732ECC55F0DC926 /* Pods-WalletConnect_Example.release.xcconfig */,
81 | AF6FEF50E52A07BBD8821D45 /* Pods-WalletConnect_Tests.debug.xcconfig */,
82 | 898BD455BC548305184BF04B /* Pods-WalletConnect_Tests.release.xcconfig */,
83 | );
84 | path = Pods;
85 | sourceTree = "";
86 | };
87 | 607FACC71AFB9204008FA782 = {
88 | isa = PBXGroup;
89 | children = (
90 | 607FACF51AFB993E008FA782 /* Podspec */,
91 | 607FACD21AFB9204008FA782 /* WalletConnectApp */,
92 | 607FACE81AFB9204008FA782 /* Tests */,
93 | 607FACD11AFB9204008FA782 /* Products */,
94 | 35A375D8C1409D77CED68BD2 /* Pods */,
95 | F19FF873C1B246C950BCFCE4 /* Frameworks */,
96 | );
97 | sourceTree = "";
98 | };
99 | 607FACD11AFB9204008FA782 /* Products */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 607FACD01AFB9204008FA782 /* WalletConnect_Example.app */,
103 | 607FACE51AFB9204008FA782 /* WalletConnect_Tests.xctest */,
104 | );
105 | name = Products;
106 | sourceTree = "";
107 | };
108 | 607FACD21AFB9204008FA782 /* WalletConnectApp */ = {
109 | isa = PBXGroup;
110 | children = (
111 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */,
112 | 607FACD71AFB9204008FA782 /* ViewController.swift */,
113 | 607FACD91AFB9204008FA782 /* Main.storyboard */,
114 | 607FACDC1AFB9204008FA782 /* Images.xcassets */,
115 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */,
116 | 607FACD31AFB9204008FA782 /* Supporting Files */,
117 | );
118 | name = WalletConnectApp;
119 | path = WalletConnect;
120 | sourceTree = "";
121 | };
122 | 607FACD31AFB9204008FA782 /* Supporting Files */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 607FACD41AFB9204008FA782 /* Info.plist */,
126 | );
127 | name = "Supporting Files";
128 | sourceTree = "";
129 | };
130 | 607FACE81AFB9204008FA782 /* Tests */ = {
131 | isa = PBXGroup;
132 | children = (
133 | BBFB765722681B18008CBC32 /* WCBinanceTradePairTests.swift */,
134 | BB3C46552257496400966B16 /* WCEncryptorTests.swift */,
135 | BB3C46562257496400966B16 /* WCSessionTests.swift */,
136 | 607FACE91AFB9204008FA782 /* Supporting Files */,
137 | );
138 | path = Tests;
139 | sourceTree = "";
140 | };
141 | 607FACE91AFB9204008FA782 /* Supporting Files */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 607FACEA1AFB9204008FA782 /* Info.plist */,
145 | );
146 | name = "Supporting Files";
147 | sourceTree = "";
148 | };
149 | 607FACF51AFB993E008FA782 /* Podspec */ = {
150 | isa = PBXGroup;
151 | children = (
152 | FF54DC7F0D5E8367EB168F5A /* WalletConnect.podspec */,
153 | 9FE02F50BAA093A28A16E601 /* README.md */,
154 | 7B51907CCB4908B80495A7C7 /* LICENSE */,
155 | );
156 | name = Podspec;
157 | sourceTree = "";
158 | };
159 | F19FF873C1B246C950BCFCE4 /* Frameworks */ = {
160 | isa = PBXGroup;
161 | children = (
162 | 58018BFAC1E050DECC1E3B9B /* Pods_WalletConnect_Example.framework */,
163 | E343012D932C98B685E7EFB2 /* Pods_WalletConnect_Tests.framework */,
164 | );
165 | name = Frameworks;
166 | sourceTree = "";
167 | };
168 | /* End PBXGroup section */
169 |
170 | /* Begin PBXNativeTarget section */
171 | 607FACCF1AFB9204008FA782 /* WalletConnect_Example */ = {
172 | isa = PBXNativeTarget;
173 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "WalletConnect_Example" */;
174 | buildPhases = (
175 | C1B9F7991B6113D359A1D332 /* [CP] Check Pods Manifest.lock */,
176 | 607FACCC1AFB9204008FA782 /* Sources */,
177 | 607FACCD1AFB9204008FA782 /* Frameworks */,
178 | 607FACCE1AFB9204008FA782 /* Resources */,
179 | A97A052E375912909E5670CC /* [CP] Embed Pods Frameworks */,
180 | );
181 | buildRules = (
182 | );
183 | dependencies = (
184 | );
185 | name = WalletConnect_Example;
186 | productName = WalletConnect;
187 | productReference = 607FACD01AFB9204008FA782 /* WalletConnect_Example.app */;
188 | productType = "com.apple.product-type.application";
189 | };
190 | 607FACE41AFB9204008FA782 /* WalletConnect_Tests */ = {
191 | isa = PBXNativeTarget;
192 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "WalletConnect_Tests" */;
193 | buildPhases = (
194 | F52DAAE2B440AE5152878E22 /* [CP] Check Pods Manifest.lock */,
195 | 607FACE11AFB9204008FA782 /* Sources */,
196 | 607FACE21AFB9204008FA782 /* Frameworks */,
197 | 607FACE31AFB9204008FA782 /* Resources */,
198 | );
199 | buildRules = (
200 | );
201 | dependencies = (
202 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */,
203 | );
204 | name = WalletConnect_Tests;
205 | productName = Tests;
206 | productReference = 607FACE51AFB9204008FA782 /* WalletConnect_Tests.xctest */;
207 | productType = "com.apple.product-type.bundle.unit-test";
208 | };
209 | /* End PBXNativeTarget section */
210 |
211 | /* Begin PBXProject section */
212 | 607FACC81AFB9204008FA782 /* Project object */ = {
213 | isa = PBXProject;
214 | attributes = {
215 | LastSwiftUpdateCheck = 0830;
216 | LastUpgradeCheck = 1020;
217 | ORGANIZATIONNAME = CocoaPods;
218 | TargetAttributes = {
219 | 607FACCF1AFB9204008FA782 = {
220 | CreatedOnToolsVersion = 6.3.1;
221 | DevelopmentTeam = FH9QG7ZJR9;
222 | LastSwiftMigration = 1020;
223 | ProvisioningStyle = Automatic;
224 | };
225 | 607FACE41AFB9204008FA782 = {
226 | CreatedOnToolsVersion = 6.3.1;
227 | DevelopmentTeam = FH9QG7ZJR9;
228 | LastSwiftMigration = 1020;
229 | TestTargetID = 607FACCF1AFB9204008FA782;
230 | };
231 | };
232 | };
233 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "WalletConnect" */;
234 | compatibilityVersion = "Xcode 3.2";
235 | developmentRegion = English;
236 | hasScannedForEncodings = 0;
237 | knownRegions = (
238 | English,
239 | en,
240 | Base,
241 | );
242 | mainGroup = 607FACC71AFB9204008FA782;
243 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
244 | projectDirPath = "";
245 | projectRoot = "";
246 | targets = (
247 | 607FACCF1AFB9204008FA782 /* WalletConnect_Example */,
248 | 607FACE41AFB9204008FA782 /* WalletConnect_Tests */,
249 | );
250 | };
251 | /* End PBXProject section */
252 |
253 | /* Begin PBXResourcesBuildPhase section */
254 | 607FACCE1AFB9204008FA782 /* Resources */ = {
255 | isa = PBXResourcesBuildPhase;
256 | buildActionMask = 2147483647;
257 | files = (
258 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
259 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
260 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */,
261 | );
262 | runOnlyForDeploymentPostprocessing = 0;
263 | };
264 | 607FACE31AFB9204008FA782 /* Resources */ = {
265 | isa = PBXResourcesBuildPhase;
266 | buildActionMask = 2147483647;
267 | files = (
268 | );
269 | runOnlyForDeploymentPostprocessing = 0;
270 | };
271 | /* End PBXResourcesBuildPhase section */
272 |
273 | /* Begin PBXShellScriptBuildPhase section */
274 | A97A052E375912909E5670CC /* [CP] Embed Pods Frameworks */ = {
275 | isa = PBXShellScriptBuildPhase;
276 | buildActionMask = 2147483647;
277 | files = (
278 | );
279 | inputFileListPaths = (
280 | );
281 | inputPaths = (
282 | "${PODS_ROOT}/Target Support Files/Pods-WalletConnect_Example/Pods-WalletConnect_Example-frameworks.sh",
283 | "${BUILT_PRODUCTS_DIR}/CryptoSwift/CryptoSwift.framework",
284 | "${BUILT_PRODUCTS_DIR}/PromiseKit/PromiseKit.framework",
285 | "${BUILT_PRODUCTS_DIR}/Starscream/Starscream.framework",
286 | "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
287 | "${BUILT_PRODUCTS_DIR}/TrustWalletCore/TrustWalletCore.framework",
288 | "${BUILT_PRODUCTS_DIR}/WalletConnect/WalletConnect.framework",
289 | );
290 | name = "[CP] Embed Pods Frameworks";
291 | outputFileListPaths = (
292 | );
293 | outputPaths = (
294 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework",
295 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework",
296 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Starscream.framework",
297 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
298 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TrustWalletCore.framework",
299 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/WalletConnect.framework",
300 | );
301 | runOnlyForDeploymentPostprocessing = 0;
302 | shellPath = /bin/sh;
303 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-WalletConnect_Example/Pods-WalletConnect_Example-frameworks.sh\"\n";
304 | showEnvVarsInLog = 0;
305 | };
306 | C1B9F7991B6113D359A1D332 /* [CP] Check Pods Manifest.lock */ = {
307 | isa = PBXShellScriptBuildPhase;
308 | buildActionMask = 2147483647;
309 | files = (
310 | );
311 | inputFileListPaths = (
312 | );
313 | inputPaths = (
314 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
315 | "${PODS_ROOT}/Manifest.lock",
316 | );
317 | name = "[CP] Check Pods Manifest.lock";
318 | outputFileListPaths = (
319 | );
320 | outputPaths = (
321 | "$(DERIVED_FILE_DIR)/Pods-WalletConnect_Example-checkManifestLockResult.txt",
322 | );
323 | runOnlyForDeploymentPostprocessing = 0;
324 | shellPath = /bin/sh;
325 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
326 | showEnvVarsInLog = 0;
327 | };
328 | F52DAAE2B440AE5152878E22 /* [CP] Check Pods Manifest.lock */ = {
329 | isa = PBXShellScriptBuildPhase;
330 | buildActionMask = 2147483647;
331 | files = (
332 | );
333 | inputFileListPaths = (
334 | );
335 | inputPaths = (
336 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
337 | "${PODS_ROOT}/Manifest.lock",
338 | );
339 | name = "[CP] Check Pods Manifest.lock";
340 | outputFileListPaths = (
341 | );
342 | outputPaths = (
343 | "$(DERIVED_FILE_DIR)/Pods-WalletConnect_Tests-checkManifestLockResult.txt",
344 | );
345 | runOnlyForDeploymentPostprocessing = 0;
346 | shellPath = /bin/sh;
347 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
348 | showEnvVarsInLog = 0;
349 | };
350 | /* End PBXShellScriptBuildPhase section */
351 |
352 | /* Begin PBXSourcesBuildPhase section */
353 | 607FACCC1AFB9204008FA782 /* Sources */ = {
354 | isa = PBXSourcesBuildPhase;
355 | buildActionMask = 2147483647;
356 | files = (
357 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
358 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
359 | );
360 | runOnlyForDeploymentPostprocessing = 0;
361 | };
362 | 607FACE11AFB9204008FA782 /* Sources */ = {
363 | isa = PBXSourcesBuildPhase;
364 | buildActionMask = 2147483647;
365 | files = (
366 | BB3C46582257496400966B16 /* WCSessionTests.swift in Sources */,
367 | BBFB765822681B18008CBC32 /* WCBinanceTradePairTests.swift in Sources */,
368 | BB3C46572257496400966B16 /* WCEncryptorTests.swift in Sources */,
369 | );
370 | runOnlyForDeploymentPostprocessing = 0;
371 | };
372 | /* End PBXSourcesBuildPhase section */
373 |
374 | /* Begin PBXTargetDependency section */
375 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = {
376 | isa = PBXTargetDependency;
377 | target = 607FACCF1AFB9204008FA782 /* WalletConnect_Example */;
378 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */;
379 | };
380 | /* End PBXTargetDependency section */
381 |
382 | /* Begin PBXVariantGroup section */
383 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = {
384 | isa = PBXVariantGroup;
385 | children = (
386 | 607FACDA1AFB9204008FA782 /* Base */,
387 | );
388 | name = Main.storyboard;
389 | sourceTree = "";
390 | };
391 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = {
392 | isa = PBXVariantGroup;
393 | children = (
394 | 607FACDF1AFB9204008FA782 /* Base */,
395 | );
396 | name = LaunchScreen.xib;
397 | sourceTree = "";
398 | };
399 | /* End PBXVariantGroup section */
400 |
401 | /* Begin XCBuildConfiguration section */
402 | 607FACED1AFB9204008FA782 /* Debug */ = {
403 | isa = XCBuildConfiguration;
404 | buildSettings = {
405 | ALWAYS_SEARCH_USER_PATHS = NO;
406 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
407 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
408 | CLANG_CXX_LIBRARY = "libc++";
409 | CLANG_ENABLE_MODULES = YES;
410 | CLANG_ENABLE_OBJC_ARC = YES;
411 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
412 | CLANG_WARN_BOOL_CONVERSION = YES;
413 | CLANG_WARN_COMMA = YES;
414 | CLANG_WARN_CONSTANT_CONVERSION = YES;
415 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
416 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
417 | CLANG_WARN_EMPTY_BODY = YES;
418 | CLANG_WARN_ENUM_CONVERSION = YES;
419 | CLANG_WARN_INFINITE_RECURSION = YES;
420 | CLANG_WARN_INT_CONVERSION = YES;
421 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
422 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
423 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
424 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
425 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
426 | CLANG_WARN_STRICT_PROTOTYPES = YES;
427 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
428 | CLANG_WARN_UNREACHABLE_CODE = YES;
429 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
430 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
431 | COPY_PHASE_STRIP = NO;
432 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
433 | ENABLE_STRICT_OBJC_MSGSEND = YES;
434 | ENABLE_TESTABILITY = YES;
435 | GCC_C_LANGUAGE_STANDARD = gnu99;
436 | GCC_DYNAMIC_NO_PIC = NO;
437 | GCC_NO_COMMON_BLOCKS = YES;
438 | GCC_OPTIMIZATION_LEVEL = 0;
439 | GCC_PREPROCESSOR_DEFINITIONS = (
440 | "DEBUG=1",
441 | "$(inherited)",
442 | );
443 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
444 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
445 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
446 | GCC_WARN_UNDECLARED_SELECTOR = YES;
447 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
448 | GCC_WARN_UNUSED_FUNCTION = YES;
449 | GCC_WARN_UNUSED_VARIABLE = YES;
450 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
451 | MTL_ENABLE_DEBUG_INFO = YES;
452 | ONLY_ACTIVE_ARCH = YES;
453 | SDKROOT = iphoneos;
454 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
455 | };
456 | name = Debug;
457 | };
458 | 607FACEE1AFB9204008FA782 /* Release */ = {
459 | isa = XCBuildConfiguration;
460 | buildSettings = {
461 | ALWAYS_SEARCH_USER_PATHS = NO;
462 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
463 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
464 | CLANG_CXX_LIBRARY = "libc++";
465 | CLANG_ENABLE_MODULES = YES;
466 | CLANG_ENABLE_OBJC_ARC = YES;
467 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
468 | CLANG_WARN_BOOL_CONVERSION = YES;
469 | CLANG_WARN_COMMA = YES;
470 | CLANG_WARN_CONSTANT_CONVERSION = YES;
471 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
472 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
473 | CLANG_WARN_EMPTY_BODY = YES;
474 | CLANG_WARN_ENUM_CONVERSION = YES;
475 | CLANG_WARN_INFINITE_RECURSION = YES;
476 | CLANG_WARN_INT_CONVERSION = YES;
477 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
478 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
479 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
480 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
481 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
482 | CLANG_WARN_STRICT_PROTOTYPES = YES;
483 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
484 | CLANG_WARN_UNREACHABLE_CODE = YES;
485 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
486 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
487 | COPY_PHASE_STRIP = NO;
488 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
489 | ENABLE_NS_ASSERTIONS = NO;
490 | ENABLE_STRICT_OBJC_MSGSEND = YES;
491 | GCC_C_LANGUAGE_STANDARD = gnu99;
492 | GCC_NO_COMMON_BLOCKS = YES;
493 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
494 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
495 | GCC_WARN_UNDECLARED_SELECTOR = YES;
496 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
497 | GCC_WARN_UNUSED_FUNCTION = YES;
498 | GCC_WARN_UNUSED_VARIABLE = YES;
499 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
500 | MTL_ENABLE_DEBUG_INFO = NO;
501 | SDKROOT = iphoneos;
502 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
503 | VALIDATE_PRODUCT = YES;
504 | };
505 | name = Release;
506 | };
507 | 607FACF01AFB9204008FA782 /* Debug */ = {
508 | isa = XCBuildConfiguration;
509 | baseConfigurationReference = 3CAB43573298CF6540303C70 /* Pods-WalletConnect_Example.debug.xcconfig */;
510 | buildSettings = {
511 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
512 | CODE_SIGN_IDENTITY = "iPhone Developer";
513 | CODE_SIGN_STYLE = Automatic;
514 | DEVELOPMENT_TEAM = FH9QG7ZJR9;
515 | INFOPLIST_FILE = WalletConnect/Info.plist;
516 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
517 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
518 | MODULE_NAME = ExampleApp;
519 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
520 | PRODUCT_NAME = "$(TARGET_NAME)";
521 | PROVISIONING_PROFILE_SPECIFIER = "";
522 | SWIFT_VERSION = 5.0;
523 | };
524 | name = Debug;
525 | };
526 | 607FACF11AFB9204008FA782 /* Release */ = {
527 | isa = XCBuildConfiguration;
528 | baseConfigurationReference = C5AB14183732ECC55F0DC926 /* Pods-WalletConnect_Example.release.xcconfig */;
529 | buildSettings = {
530 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
531 | CODE_SIGN_IDENTITY = "iPhone Developer";
532 | CODE_SIGN_STYLE = Automatic;
533 | DEVELOPMENT_TEAM = FH9QG7ZJR9;
534 | INFOPLIST_FILE = WalletConnect/Info.plist;
535 | IPHONEOS_DEPLOYMENT_TARGET = 11.0;
536 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
537 | MODULE_NAME = ExampleApp;
538 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
539 | PRODUCT_NAME = "$(TARGET_NAME)";
540 | PROVISIONING_PROFILE_SPECIFIER = "";
541 | SWIFT_VERSION = 5.0;
542 | };
543 | name = Release;
544 | };
545 | 607FACF31AFB9204008FA782 /* Debug */ = {
546 | isa = XCBuildConfiguration;
547 | baseConfigurationReference = AF6FEF50E52A07BBD8821D45 /* Pods-WalletConnect_Tests.debug.xcconfig */;
548 | buildSettings = {
549 | CLANG_ENABLE_MODULES = YES;
550 | DEVELOPMENT_TEAM = FH9QG7ZJR9;
551 | GCC_PREPROCESSOR_DEFINITIONS = (
552 | "DEBUG=1",
553 | "$(inherited)",
554 | );
555 | INFOPLIST_FILE = Tests/Info.plist;
556 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
557 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
558 | PRODUCT_NAME = "$(TARGET_NAME)";
559 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
560 | SWIFT_VERSION = 5.0;
561 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WalletConnect_Example.app/WalletConnect_Example";
562 | };
563 | name = Debug;
564 | };
565 | 607FACF41AFB9204008FA782 /* Release */ = {
566 | isa = XCBuildConfiguration;
567 | baseConfigurationReference = 898BD455BC548305184BF04B /* Pods-WalletConnect_Tests.release.xcconfig */;
568 | buildSettings = {
569 | CLANG_ENABLE_MODULES = YES;
570 | DEVELOPMENT_TEAM = FH9QG7ZJR9;
571 | INFOPLIST_FILE = Tests/Info.plist;
572 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
573 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
574 | PRODUCT_NAME = "$(TARGET_NAME)";
575 | SWIFT_VERSION = 5.0;
576 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/WalletConnect_Example.app/WalletConnect_Example";
577 | };
578 | name = Release;
579 | };
580 | /* End XCBuildConfiguration section */
581 |
582 | /* Begin XCConfigurationList section */
583 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "WalletConnect" */ = {
584 | isa = XCConfigurationList;
585 | buildConfigurations = (
586 | 607FACED1AFB9204008FA782 /* Debug */,
587 | 607FACEE1AFB9204008FA782 /* Release */,
588 | );
589 | defaultConfigurationIsVisible = 0;
590 | defaultConfigurationName = Release;
591 | };
592 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "WalletConnect_Example" */ = {
593 | isa = XCConfigurationList;
594 | buildConfigurations = (
595 | 607FACF01AFB9204008FA782 /* Debug */,
596 | 607FACF11AFB9204008FA782 /* Release */,
597 | );
598 | defaultConfigurationIsVisible = 0;
599 | defaultConfigurationName = Release;
600 | };
601 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "WalletConnect_Tests" */ = {
602 | isa = XCConfigurationList;
603 | buildConfigurations = (
604 | 607FACF31AFB9204008FA782 /* Debug */,
605 | 607FACF41AFB9204008FA782 /* Release */,
606 | );
607 | defaultConfigurationIsVisible = 0;
608 | defaultConfigurationName = Release;
609 | };
610 | /* End XCConfigurationList section */
611 | };
612 | rootObject = 607FACC81AFB9204008FA782 /* Project object */;
613 | }
614 |
--------------------------------------------------------------------------------
/Example/WalletConnect.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/WalletConnect.xcodeproj/xcshareddata/xcschemes/WalletConnect-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
78 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
99 |
105 |
106 |
107 |
108 |
110 |
111 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Example/WalletConnect.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/WalletConnect/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // WalletConnectApp
4 | //
5 | // Created by Tao Xu on 3/29/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | return true
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/Example/WalletConnect/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/Example/WalletConnect/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
36 |
43 |
50 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/Example/WalletConnect/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "size" : "1024x1024",
46 | "scale" : "1x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/Example/WalletConnect/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Example/WalletConnect/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // WalletConnectApp
4 | //
5 | // Created by Tao Xu on 3/29/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import WalletConnect
11 | import PromiseKit
12 | import TrustWalletCore
13 |
14 | class ViewController: UIViewController {
15 |
16 | @IBOutlet weak var uriField: UITextField!
17 | @IBOutlet weak var addressField: UITextField!
18 | @IBOutlet weak var chainIdField: UITextField!
19 | @IBOutlet weak var connectButton: UIButton!
20 | @IBOutlet weak var approveButton: UIButton!
21 |
22 | var interactor: WCInteractor?
23 | let clientMeta = WCPeerMeta(name: "WalletConnect SDK", url: "https://github.com/TrustWallet/wallet-connect-swift")
24 |
25 | let privateKey = PrivateKey(data: Data(hexString: "ba005cd605d8a02e3d5dfd04234cef3a3ee4f76bfbad2722d1fb5af8e12e6764")!)!
26 |
27 | var defaultAddress: String = ""
28 | var defaultChainId: Int = 1
29 |
30 | override func viewDidLoad() {
31 | super.viewDidLoad()
32 |
33 | let string = "wc:d282a614-a21f-4226-aca1-1db4ecfa2c08@1?bridge=https%3A%2F%2Fbridge.walletconnect.org&key=3890ad13ed17ce298fc7369eef7e6359864dc11c1ba5434e782c6277dc00d151"
34 |
35 | defaultAddress = CoinType.ethereum.deriveAddress(privateKey: privateKey)
36 | uriField.text = string
37 | addressField.text = defaultAddress
38 | chainIdField.text = "1"
39 | chainIdField.textAlignment = .center
40 | approveButton.isEnabled = false
41 | }
42 |
43 | func connect(session: WCSession) {
44 | print("==> session", session)
45 | let interactor = WCInteractor(session: session, meta: clientMeta)
46 |
47 | configure(interactor: interactor)
48 |
49 | interactor.connect().done { [weak self] connected in
50 | self?.connectionStatusUpdated(connected)
51 | }.cauterize()
52 |
53 | self.interactor = interactor
54 | }
55 |
56 | func configure(interactor: WCInteractor) {
57 | let accounts = [defaultAddress]
58 | let chainId = defaultChainId
59 |
60 | interactor.onSessionRequest = { [weak self] (id, peer) in
61 | let message = [peer.description, peer.url].joined(separator: "\n")
62 | let alert = UIAlertController(title: peer.name, message: message, preferredStyle: .alert)
63 | alert.addAction(UIAlertAction(title: "Reject", style: .destructive, handler: { _ in
64 | self?.interactor?.rejectSession().cauterize()
65 | }))
66 | alert.addAction(UIAlertAction(title: "Approve", style: .default, handler: { _ in
67 | self?.interactor?.approveSession(accounts: accounts, chainId: chainId).cauterize()
68 | }))
69 | self?.show(alert, sender: nil)
70 | }
71 |
72 | interactor.onDisconnect = { [weak self] (error) in
73 | self?.connectionStatusUpdated(false)
74 | }
75 |
76 | interactor.onEthSign = { [weak self] (id, params) in
77 | let alert = UIAlertController(title: "eth_sign", message: params[1], preferredStyle: .alert)
78 | alert.addAction(UIAlertAction(title: "Cancel", style: .destructive, handler: nil))
79 | alert.addAction(UIAlertAction(title: "Sign", style: .default, handler: { _ in
80 | self?.signEth(id: id, message: params[1])
81 | }))
82 | self?.show(alert, sender: nil)
83 | }
84 |
85 | interactor.onEthSendTransaction = { [weak self] (id, transaction) in
86 | let data = try! JSONEncoder().encode(transaction)
87 | let message = String(data: data, encoding: .utf8)
88 | let alert = UIAlertController(title: "eth_sendTransaction", message: message, preferredStyle: .alert)
89 | alert.addAction(UIAlertAction(title: "Reject", style: .destructive, handler: { _ in
90 | self?.interactor?.rejectRequest(id: id, message: "I don't have ethers").cauterize()
91 | }))
92 | self?.show(alert, sender: nil)
93 | }
94 |
95 | interactor.onBnbSign = { [weak self] (id, order) in
96 | let message = order.encodedString
97 | let alert = UIAlertController(title: "bnb_sign", message: message, preferredStyle: .alert)
98 | alert.addAction(UIAlertAction(title: "Cancel", style: .destructive, handler: nil))
99 | alert.addAction(UIAlertAction(title: "Sign", style: .default, handler: { [weak self] _ in
100 | self?.signBnbOrder(id: id, order: order)
101 | }))
102 | self?.show(alert, sender: nil)
103 | }
104 | }
105 |
106 | func approve(accounts: [String], chainId: Int) {
107 | interactor?.approveSession(accounts: accounts, chainId: chainId).done {
108 | print("<== approveSession done")
109 | }.cauterize()
110 | }
111 |
112 | func signEth(id: Int64, message: String) {
113 | guard let data = message.data(using: .utf8) else {
114 | print("invalid message")
115 | return
116 | }
117 | let prefix = "\u{19}Ethereum Signed Message:\n\(data.count)".data(using: .utf8)!
118 | var result = privateKey.sign(digest: Hash.keccak256(data: prefix + data), curve: .secp256k1)!
119 | result[64] += 27
120 | self.interactor?.approveRequest(id: id, result: result.hexString).cauterize()
121 | }
122 |
123 | func signBnbOrder(id: Int64, order: WCBinanceOrder) {
124 | let data = order.encoded
125 | print("==> signbnbOrder", String(data: data, encoding: .utf8)!)
126 | let signature = privateKey.sign(digest: Hash.sha256(data: data), curve: .secp256k1)!
127 | let signed = WCBinanceOrderSignature(
128 | signature: signature.dropLast().hexString,
129 | publicKey: privateKey.getPublicKeySecp256k1(compressed: false).data.hexString
130 | )
131 | interactor?.approveBnbOrder(id: id, signed: signed).done({ confirm in
132 | print("<== approveBnbOrder", confirm)
133 | }).cauterize()
134 | }
135 |
136 | func connectionStatusUpdated(_ connected: Bool) {
137 | self.approveButton.isEnabled = connected
138 | self.connectButton.setTitle(!connected ? "Connect" : "Disconnect", for: .normal)
139 | }
140 |
141 | @IBAction func connectTapped() {
142 | guard let string = uriField.text, let session = WCSession.from(string: string) else {
143 | print("invalid uri: \(String(describing: uriField.text))")
144 | return
145 | }
146 | if let i = interactor, i.connected {
147 | i.killSession().done { [weak self] in
148 | self?.approveButton.isEnabled = false
149 | self?.connectButton.setTitle("Connect", for: .normal)
150 | }.cauterize()
151 | } else {
152 | connect(session: session)
153 | }
154 | }
155 |
156 | @IBAction func approveTapped() {
157 | guard let address = addressField.text,
158 | let chainIdString = chainIdField.text else {
159 | print("empty address or chainId")
160 | return
161 | }
162 | guard let chainId = Int(chainIdString) else {
163 | print("invalid chainId")
164 | return
165 | }
166 | guard EthereumAddress.isValidString(string: address) || TendermintAddress.isValidString(string: address) else {
167 | print("invalid eth or bnb address")
168 | return
169 | }
170 | approve(accounts: [address], chainId: chainId)
171 | }
172 | }
173 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2019 Igor Shmakov
4 | Copyright (c) 2019 hewigovens <360470+hewigovens@users.noreply.github.com>
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all
14 | copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WalletConnect Swift SDK
2 |
3 | [Deprecated] Please refer to [wallet-connect-swift](https://github.com/WalletConnect/wallet-connect-swift) repo
4 |
--------------------------------------------------------------------------------
/WalletConnect.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = 'WalletConnect'
3 | s.version = '0.1.0'
4 | s.summary = 'WalletConnect Swift SDK'
5 | s.description = 'WalletConnect Swift SDK'
6 |
7 | s.homepage = 'https://github.com/hewigovens/wallet-connect-swift'
8 | s.license = { :type => 'MIT', :file => 'LICENSE' }
9 | s.author = { 'hewigovens' => '360470+hewigovens@users.noreply.github.com' }
10 | s.source = { :git => 'https://github.com/hewigovens/WalletConnect.git', :tag => s.version.to_s }
11 |
12 | s.ios.deployment_target = '11.0'
13 | s.source_files = 'WalletConnect/**/*'
14 | s.swift_version = '5.0'
15 |
16 | s.dependency 'CryptoSwift'
17 | s.dependency 'Starscream'
18 | s.dependency 'PromiseKit'
19 | end
20 |
--------------------------------------------------------------------------------
/WalletConnect/Assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WalletConnect/swift-walletconnect-lib/4204495771bc5eaee45d7381f0c71de1a65081a0/WalletConnect/Assets/.gitkeep
--------------------------------------------------------------------------------
/WalletConnect/Extensions/Data+Hex.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Data+Hex.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 3/30/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CryptoSwift
11 |
12 | extension Data {
13 | var hex: String {
14 | return self.toHexString()
15 | }
16 | }
17 |
18 | extension JSONEncoder {
19 | func encodeAsUTF8(_ value: T) -> String where T : Encodable {
20 | guard let data = try? self.encode(value),
21 | let string = String(data: data, encoding: .utf8) else {
22 | return ""
23 | }
24 | return string
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/WalletConnect/Extensions/Encodable+Extension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Encodable+Extension.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/1/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | extension Encodable {
12 | public var encoded: Data {
13 | let encoder = JSONEncoder()
14 | encoder.outputFormatting = [.sortedKeys]
15 | return try! encoder.encode(self)
16 | }
17 | public var encodedString: String {
18 | return String(data: encoded, encoding: .utf8)!
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/WalletConnect/JSONRPC/JSONRPC.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JSONRPC.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 3/29/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let JSONRPCVersion = "2.0"
12 |
13 | struct JSONRPCError: Error, Codable {
14 | let code: Int
15 | let message: String
16 | }
17 |
18 | struct JSONRPCRequest: Codable {
19 | let id: Int64
20 | let jsonrpc = JSONRPCVersion
21 | let method: String
22 | let params: T
23 | }
24 |
25 | struct JSONRPCResponse: Codable {
26 | let jsonrpc = JSONRPCVersion
27 | let id: Int64
28 | let result: T
29 |
30 | enum CodingKeys: String, CodingKey {
31 | case jsonrpc
32 | case id
33 | case result
34 | case error
35 | }
36 |
37 | init(id: Int64, result: T) {
38 | self.id = id
39 | self.result = result
40 | }
41 | }
42 |
43 | struct JSONRPCErrorResponse: Codable {
44 | let jsonrpc = JSONRPCVersion
45 | let id: Int64
46 | let error: JSONRPCError
47 | }
48 |
49 | extension JSONRPCResponse {
50 | func encode(to encoder: Encoder) throws {
51 | var container = encoder.container(keyedBy: CodingKeys.self)
52 | try container.encode(id, forKey: .id)
53 | try container.encode(jsonrpc, forKey: .jsonrpc)
54 | try container.encode(result, forKey: .result)
55 | }
56 |
57 | init(from decoder: Decoder) throws {
58 | let values = try decoder.container(keyedBy: CodingKeys.self)
59 | if let error = try values.decodeIfPresent(JSONRPCError.self, forKey: .error) {
60 | throw error
61 | }
62 | self.id = try values.decode(Int64.self, forKey: .id)
63 | self.result = try values.decode(T.self, forKey: .result)
64 | }
65 | }
66 |
67 | public func generateId() -> Int64 {
68 | return Int64(Date().timeIntervalSince1970) * 1000
69 | }
70 |
--------------------------------------------------------------------------------
/WalletConnect/Models/Binance/WCBinanceCancelOrder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCBinanceCancelOrder.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/7/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct WCBinanceCancelOrder: WCBinanceOrder, Codable {
12 | public struct Message: Codable {
13 | public let refid: String
14 | public let sender: String
15 | public let symbol: String
16 | }
17 | public let account_number: String
18 | public let chain_id: String
19 | public let data: String?
20 | public let memo: String
21 | public let msgs: [Message]
22 | public let sequence: String
23 | public let source: String
24 |
25 | public func encode(to encoder: Encoder) throws {
26 | var container = encoder.container(keyedBy: CodingKeys.self)
27 | try container.encode(account_number, forKey: .account_number)
28 | try container.encode(chain_id, forKey: .chain_id)
29 | try container.encode(data, forKey: .data)
30 | try container.encode(memo, forKey: .memo)
31 | try container.encode(msgs, forKey: .msgs)
32 | try container.encode(sequence, forKey: .sequence)
33 | try container.encode(source, forKey: .source)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/WalletConnect/Models/Binance/WCBinanceOrder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCBinanceOrderParam.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/2/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public protocol WCBinanceOrder {
12 | var encoded: Data { get }
13 | var encodedString: String { get }
14 | }
15 |
16 | public struct WCBinanceOrderSignature: Codable {
17 | public let signature: String
18 | public let publicKey: String
19 |
20 | public init(signature: String, publicKey: String) {
21 | self.signature = signature
22 | self.publicKey = publicKey
23 | }
24 | }
25 |
26 | public struct WCBinanceTxConfirmParam: Codable {
27 | public let ok: Bool
28 | public let errorMsg: String?
29 | }
30 |
--------------------------------------------------------------------------------
/WalletConnect/Models/Binance/WCBinanceTradeOrder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCBinanceOrderParam.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/2/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct WCBinanceTradeOrder: WCBinanceOrder, Codable {
12 | public struct Message: Codable {
13 | public let id: String
14 | public let ordertype: Int
15 | public let price: Int
16 | public let quantity: Int64
17 | public let sender: String
18 | public let side: Int
19 | public let symbol: String
20 | public let timeinforce: Int
21 | }
22 | public let account_number: String
23 | public let chain_id: String
24 | public let data: String?
25 | public let memo: String
26 | public let msgs: [Message]
27 | public let sequence: String
28 | public let source: String
29 |
30 | public func encode(to encoder: Encoder) throws {
31 | var container = encoder.container(keyedBy: CodingKeys.self)
32 | try container.encode(account_number, forKey: .account_number)
33 | try container.encode(chain_id, forKey: .chain_id)
34 | try container.encode(data, forKey: .data)
35 | try container.encode(memo, forKey: .memo)
36 | try container.encode(msgs, forKey: .msgs)
37 | try container.encode(sequence, forKey: .sequence)
38 | try container.encode(source, forKey: .source)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/WalletConnect/Models/Binance/WCBinanceTradePair.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCBinanceTradePair.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/18/19.
6 | //
7 |
8 | import Foundation
9 |
10 | public struct WCBinanceTradePair {
11 | public let from: String
12 | public let to: String
13 |
14 | public static func from(_ symbol: String) -> WCBinanceTradePair? {
15 | let pair = symbol.split(separator: "_")
16 | guard pair.count > 1 else { return nil }
17 | let first_parts = pair[0].split(separator: "-")
18 | let second_parts = pair[1].split(separator: "-")
19 | return WCBinanceTradePair(from: String(first_parts[0]), to: String(second_parts[0]))
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/WalletConnect/Models/Binance/WCBinanceTransferOrder.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCBinanceTransferOrder.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/7/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct WCBinanceTransferOrder: WCBinanceOrder, Codable {
12 | public struct Message: Codable {
13 | public struct Coin: Codable {
14 | public let amount: Int64
15 | public let denom: String
16 | }
17 | public struct Item: Codable {
18 | public let address: String
19 | public let coins: [Coin]
20 | }
21 | public let inputs: [Item]
22 | public let outputs: [Item]
23 | }
24 |
25 | public let account_number: String
26 | public let chain_id: String
27 | public let data: String?
28 | public let memo: String
29 | public let msgs: [Message]
30 | public let sequence: String
31 | public let source: String
32 |
33 | public func encode(to encoder: Encoder) throws {
34 | var container = encoder.container(keyedBy: CodingKeys.self)
35 | try container.encode(account_number, forKey: .account_number)
36 | try container.encode(chain_id, forKey: .chain_id)
37 | try container.encode(data, forKey: .data)
38 | try container.encode(memo, forKey: .memo)
39 | try container.encode(msgs, forKey: .msgs)
40 | try container.encode(sequence, forKey: .sequence)
41 | try container.encode(source, forKey: .source)
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/WalletConnect/Models/Ethereum/WCEthereumSendTransaction.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCEthereumSendTransaction.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/3/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct WCEthereumSendTransaction: Codable {
12 | public let from: String
13 | public let to: String
14 | public let nonce: String
15 | public let gasPrice: String
16 | public let gasLimit: String
17 | public let value: String
18 | public let data: String
19 | }
20 |
--------------------------------------------------------------------------------
/WalletConnect/Models/WCEvent.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCEvent.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/1/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum WCEvent: String {
12 | case sessionRequest = "wc_sessionRequest"
13 | case sessionUpdate = "wc_sessionUpdate"
14 | case exchangeKey = "wc_exchangeKey"
15 |
16 | case ethSign = "eth_sign"
17 | case ethPersonalSign = "personal_sign"
18 | case ethSignTypeData = "eth_signTypedData"
19 | case ethSendTransaction = "eth_sendTransaction"
20 |
21 | case bnbSign = "bnb_sign"
22 | case bnbTransactionConfirm = "bnb_tx_confirmation"
23 | }
24 |
25 | extension WCEvent {
26 | func decode(_ data: Data) throws -> JSONRPCRequest {
27 | return try JSONDecoder().decode(JSONRPCRequest.self, from: data)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/WalletConnect/Models/WCPeerMeta.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCClientMeta.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 4/1/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct WCPeerMeta: Codable {
12 | public let name: String
13 | public let url: String
14 | public let description: String
15 | public let icons: [String]
16 |
17 |
18 | public init(name: String, url: String, description: String = "", icons: [String] = []) {
19 | self.name = name
20 | self.url = url
21 | self.description = description
22 | self.icons = icons
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/WalletConnect/Models/WCSessionModels.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // WCSessionUpdate.swift
4 | // WalletConnect
5 | //
6 | // Created by Tao Xu on 3/29/19.
7 | // Copyright © 2019 Trust. All rights reserved.
8 | //
9 |
10 | import Foundation
11 |
12 | public struct WCExchangeKeyParam: Codable {
13 | let peerId: String
14 | let peerMeta: WCPeerMeta
15 | let nextKey: String
16 | }
17 |
18 | public struct WCSessionRequestParam: Codable {
19 | let peerId: String
20 | let peerMeta: WCPeerMeta
21 | let chainId: String?
22 | }
23 |
24 | public struct WCSessionUpdateParam: Codable {
25 | public let approved: Bool
26 | public let chainId: Int?
27 | public let accounts: [String]?
28 |
29 | public func encode(to encoder: Encoder) throws {
30 | var container = encoder.container(keyedBy: CodingKeys.self)
31 | try container.encode(approved, forKey: .approved)
32 | try container.encode(chainId, forKey: .chainId)
33 | try container.encode(accounts, forKey: .accounts)
34 | }
35 | }
36 |
37 | public struct WCApproveSessionResponse: Codable {
38 | public let approved: Bool
39 | public let chainId: Int
40 | public let accounts: [String]
41 |
42 | public let peerId: String?
43 | public let peerMeta: WCPeerMeta?
44 | }
45 |
--------------------------------------------------------------------------------
/WalletConnect/Models/WCSocketMessage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SocketMessage.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 3/29/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public struct WCEncryptionPayload: Codable {
12 | public let data: String
13 | public let hmac: String
14 | public let iv: String
15 |
16 | public init(data: String, hmac: String, iv: String) {
17 | self.data = data
18 | self.hmac = hmac
19 | self.iv = iv
20 | }
21 | }
22 |
23 | public struct WCSocketMessage: Codable {
24 | public enum MessageType: String, Codable {
25 | case pub
26 | case sub
27 | }
28 | public let topic: String
29 | public let type: MessageType
30 | public let payload: T
31 | }
32 |
33 | public extension WCEncryptionPayload {
34 | static func extract(_ string: String) -> (topic: String, payload: WCEncryptionPayload)? {
35 | guard let data = string.data(using: .utf8) else {
36 | return nil
37 | }
38 | do {
39 | let decoder = JSONDecoder()
40 | if let message = try? decoder.decode(WCSocketMessage.self, from: data) {
41 | return (message.topic, message.payload)
42 | } else {
43 | let message = try decoder.decode(WCSocketMessage.self, from: data)
44 | let payloadData = message.payload.data(using: .utf8)
45 | return (message.topic, try decoder.decode(WCEncryptionPayload.self, from: payloadData!))
46 | }
47 | } catch let error {
48 | print(error)
49 | }
50 | return nil
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/WalletConnect/WCEncryptor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCEncryptor.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 3/30/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CryptoSwift
11 | import Security
12 |
13 | public struct WCEncryptor {
14 | public static func encrypt(data: Data, with key: Data) throws -> WCEncryptionPayload {
15 | let ivBytes = randomBytes(16)
16 | let keyBytes = key.bytes
17 | let aesCipher = try AES(key: keyBytes, blockMode: CBC(iv: ivBytes))
18 | let cipherInput = data.bytes
19 | let encryptedBytes = try aesCipher.encrypt(cipherInput)
20 |
21 | let data = encryptedBytes.toHexString()
22 | let iv = ivBytes.toHexString()
23 | let hmac = try computeHMAC(payload: data, iv: iv, key: keyBytes)
24 |
25 | return WCEncryptionPayload(data: data, hmac: hmac, iv: iv)
26 | }
27 |
28 | public static func decrypt(payload: WCEncryptionPayload, with key: Data) throws -> Data {
29 | let keyBytes = key.bytes
30 | let computedHmac = try computeHMAC(payload: payload.data, iv: payload.iv, key: keyBytes)
31 |
32 | guard computedHmac == payload.hmac else {
33 | throw WCError.badServerResponse
34 | }
35 |
36 | let dataBytes = Data(hex: payload.data).bytes
37 | let ivBytes = Data(hex: payload.iv).bytes
38 | let aesCipher = try AES(key: keyBytes, blockMode: CBC(iv: ivBytes))
39 | let decryptedBytes = try aesCipher.decrypt(dataBytes)
40 |
41 | return Data(decryptedBytes)
42 | }
43 |
44 | static func computeHMAC(payload: String, iv: String, key: [UInt8]) throws -> String {
45 | let payloadBytes = Data(hex: payload)
46 | let ivBytes = Data(hex: iv)
47 |
48 | let data = payloadBytes + ivBytes
49 | let hmacBytes = try HMAC(key: key, variant: .sha256).authenticate(data.bytes)
50 | let hmac = Data(hmacBytes).hex
51 | return hmac
52 | }
53 |
54 | static func randomBytes(_ n: Int) -> [UInt8] {
55 | var bytes = [UInt8].init(repeating: 0, count: n)
56 | let status = SecRandomCopyBytes(kSecRandomDefault, bytes.count, &bytes)
57 | if status != errSecSuccess {
58 | for i in 1...bytes.count {
59 | bytes[i] = UInt8(arc4random_uniform(256))
60 | }
61 | }
62 | return bytes
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/WalletConnect/WCError.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCError.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 3/30/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | public enum WCError: Error {
12 | case badServerResponse
13 | case badJSONRPCRequest
14 | case invalidSession
15 | case unknown
16 | }
17 |
--------------------------------------------------------------------------------
/WalletConnect/WCInteractor.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCInteractor.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 3/29/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import Starscream
11 | import PromiseKit
12 |
13 | public typealias SessionRequestClosure = (_ id: Int64, _ peer: WCPeerMeta) -> Void
14 | public typealias DisconnectClosure = (Error?) -> Void
15 | public typealias EthSignClosure = (_ id: Int64, _ params: [String]) -> Void
16 | public typealias EthSendTransactionClosure = (_ id: Int64, _ transaction: WCEthereumSendTransaction) -> Void
17 | public typealias BnbSignClosure = (_ id: Int64, _ order: WCBinanceOrder) -> Void
18 |
19 | func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
20 | #if DEBUG
21 | items.forEach {
22 | Swift.print($0, separator: separator, terminator: terminator)
23 | }
24 | #endif
25 | }
26 |
27 | public class WCInteractor {
28 | public let session: WCSession
29 | public var connected: Bool {
30 | return socket.isConnected
31 | }
32 |
33 | public let clientId: String
34 | public let clientMeta: WCPeerMeta
35 |
36 | // incoming event handlers
37 | public var onSessionRequest: SessionRequestClosure?
38 | public var onDisconnect: DisconnectClosure?
39 | public var onEthSign: EthSignClosure?
40 | public var onEthSendTransaction: EthSendTransactionClosure?
41 | public var onBnbSign: BnbSignClosure?
42 |
43 | // outgoing promise resolvers
44 | var connectResolver: Resolver?
45 | var bnbTxConfirmResolvers: [Int64: Resolver] = [:]
46 |
47 | private let socket: WebSocket
48 | private var handshakeId: Int64 = -1
49 | private var pingTimer: Timer?
50 |
51 | private var peerId: String?
52 | private var peerMeta: WCPeerMeta?
53 |
54 | public init(session: WCSession, meta: WCPeerMeta) {
55 | self.session = session
56 | self.clientId = (UIDevice.current.identifierForVendor ?? UUID()).description.lowercased()
57 | self.clientMeta = meta
58 | self.socket = WebSocket.init(url: session.bridge)
59 |
60 | socket.onConnect = { [weak self] in self?.onConnect() }
61 | socket.onDisconnect = { [weak self] error in self?.onDisconnect(error: error) }
62 | socket.onText = { [weak self] text in self?.onReceiveMessage(text: text) }
63 | socket.onPong = { _ in print("<== pong") }
64 | socket.onData = { data in print("<== websocketDidReceiveData: \(data.toHexString())") }
65 | }
66 |
67 | deinit {
68 | disconnect()
69 | }
70 |
71 | public func connect() -> Promise {
72 | if socket.isConnected {
73 | return Promise.value(true)
74 | }
75 | socket.connect()
76 | return Promise { [weak self] seal in
77 | self?.connectResolver = seal
78 | }
79 | }
80 |
81 | public func disconnect() {
82 | pingTimer?.invalidate()
83 | socket.disconnect()
84 | connectResolver = nil
85 | handshakeId = -1
86 | }
87 |
88 | public func approveSession(accounts: [String], chainId: Int) -> Promise {
89 | guard handshakeId > 0 else {
90 | return Promise(error: WCError.invalidSession)
91 | }
92 | let result = WCApproveSessionResponse(
93 | approved: true,
94 | chainId: chainId,
95 | accounts: accounts,
96 | peerId: clientId,
97 | peerMeta: clientMeta
98 | )
99 | let response = JSONRPCResponse(id: handshakeId, result: result)
100 | return encryptAndSend(data: response.encoded)
101 | }
102 |
103 | public func rejectSession(_ message: String = "Session Rejected") -> Promise {
104 | guard handshakeId > 0 else {
105 | return Promise(error: WCError.invalidSession)
106 | }
107 | let response = JSONRPCErrorResponse(id: handshakeId, error: JSONRPCError(code: -32000, message: message))
108 | return encryptAndSend(data: response.encoded)
109 | }
110 |
111 | public func killSession() -> Promise {
112 | let result = WCSessionUpdateParam(approved: false, chainId: nil, accounts: nil)
113 | let response = JSONRPCRequest(id: generateId(), method: WCEvent.sessionUpdate.rawValue, params: [result])
114 | return encryptAndSend(data: response.encoded)
115 | .map { [weak self] in
116 | self?.disconnect()
117 | }
118 | }
119 |
120 | public func approveBnbOrder(id: Int64, signed: WCBinanceOrderSignature) -> Promise {
121 | let result = signed.encodedString
122 | return approveRequest(id: id, result: result)
123 | .then { _ -> Promise in
124 | return Promise { [weak self] seal in
125 | self?.bnbTxConfirmResolvers[id] = seal
126 | }
127 | }
128 | }
129 |
130 | public func approveRequest(id: Int64, result: String) -> Promise {
131 | let response = JSONRPCResponse(id: id, result: result)
132 | return encryptAndSend(data: response.encoded)
133 | }
134 |
135 | public func rejectRequest(id: Int64, message: String) -> Promise {
136 | let response = JSONRPCErrorResponse(id: id, error: JSONRPCError(code: -32000, message: message))
137 | return encryptAndSend(data: response.encoded)
138 | }
139 | }
140 |
141 | extension WCInteractor {
142 | private func subscribe(topic: String) {
143 | let message = WCSocketMessage(topic: topic, type: .sub, payload: "")
144 | let data = try! JSONEncoder().encode(message)
145 | socket.write(data: data)
146 | print("==> subscribe: \(String(data: data, encoding: .utf8)!)")
147 | }
148 |
149 | private func encryptAndSend(data: Data) -> Promise {
150 | print("==> encrypt: \(String(data: data, encoding: .utf8)!) ")
151 | let encoder = JSONEncoder()
152 | let payload = try! WCEncryptor.encrypt(data: data, with: session.key)
153 | let payloadString = encoder.encodeAsUTF8(payload)
154 | let message = WCSocketMessage(topic: peerId ?? session.topic, type: .pub, payload: payloadString)
155 | let data = message.encoded
156 | return Promise { seal in
157 | socket.write(data: data) {
158 | print("==> sent \(String(data: data, encoding: .utf8)!) ")
159 | seal.fulfill(())
160 | }
161 | }
162 | }
163 |
164 | private func handleEvent(_ event: WCEvent, topic: String, decrypted: Data) {
165 | do {
166 | switch event {
167 | // topic == session.topic
168 | case .sessionRequest:
169 | let request: JSONRPCRequest<[WCSessionRequestParam]> = try event.decode(decrypted)
170 | guard let params = request.params.first else {
171 | throw WCError.badJSONRPCRequest
172 | }
173 | handshakeId = request.id
174 | peerId = params.peerId
175 | peerMeta = params.peerMeta
176 | onSessionRequest?(request.id, params.peerMeta)
177 | // topic == clientId
178 | case .ethSign, .ethPersonalSign:
179 | let request: JSONRPCRequest<[String]> = try event.decode(decrypted)
180 | onEthSign?(request.id, request.params)
181 | case .ethSendTransaction:
182 | let request: JSONRPCRequest<[WCEthereumSendTransaction]> = try event.decode(decrypted)
183 | guard request.params.count > 0 else {
184 | throw WCError.badJSONRPCRequest
185 | }
186 | onEthSendTransaction?(request.id, request.params[0])
187 | case .bnbSign:
188 | if let request: JSONRPCRequest<[WCBinanceTradeOrder]> = try? event.decode(decrypted) {
189 | onBnbSign?(request.id, request.params[0])
190 | } else if let request: JSONRPCRequest<[WCBinanceCancelOrder]> = try? event.decode(decrypted) {
191 | onBnbSign?(request.id, request.params[0])
192 | } else if let request: JSONRPCRequest<[WCBinanceTransferOrder]> = try? event.decode(decrypted) {
193 | onBnbSign?(request.id, request.params[0])
194 | }
195 | break
196 | case .bnbTransactionConfirm:
197 | let request: JSONRPCRequest<[WCBinanceTxConfirmParam]> = try event.decode(decrypted)
198 | guard request.params.count > 0 else {
199 | throw WCError.badJSONRPCRequest
200 | }
201 | bnbTxConfirmResolvers[request.id]?.fulfill(request.params[0])
202 | bnbTxConfirmResolvers[request.id] = nil
203 | case .sessionUpdate:
204 | let request: JSONRPCRequest<[WCSessionUpdateParam]> = try event.decode(decrypted)
205 | guard let param = request.params.first else {
206 | throw WCError.badJSONRPCRequest
207 | }
208 | if param.approved == false {
209 | disconnect()
210 | }
211 | default:
212 | break
213 | }
214 | } catch let error {
215 | print("==> handleEvent error: \(error.localizedDescription)")
216 | }
217 | }
218 | }
219 | extension WCInteractor {
220 |
221 | private func onConnect() {
222 | print("<== websocketDidConnect")
223 | pingTimer = Timer.scheduledTimer(withTimeInterval: 15, repeats: true, block: { [weak socket] _ in
224 | print("==> ping")
225 | socket?.write(ping: Data())
226 | })
227 | subscribe(topic: session.topic)
228 | subscribe(topic: clientId)
229 | connectResolver?.fulfill(true)
230 | connectResolver = nil
231 | }
232 |
233 | private func onDisconnect(error: Error?) {
234 | print("<== websocketDidDisconnect, error: \(error.debugDescription)")
235 | pingTimer?.invalidate()
236 | if let error = error {
237 | connectResolver?.reject(error)
238 | } else {
239 | connectResolver?.fulfill(false)
240 | }
241 | connectResolver = nil
242 | onDisconnect?(error)
243 | }
244 |
245 | private func onReceiveMessage(text: String) {
246 | print("<== receive: \(text)")
247 | guard let (topic, payload) = WCEncryptionPayload.extract(text) else { return }
248 | do {
249 | let decrypted = try WCEncryptor.decrypt(payload: payload, with: session.key)
250 | guard let json = try JSONSerialization.jsonObject(with: decrypted, options: [])
251 | as? [String: Any] else {
252 | throw WCError.badServerResponse
253 | }
254 | print("<== decrypted: \(String(data: decrypted, encoding: .utf8)!)")
255 | if let method = json["method"] as? String,
256 | let event = WCEvent(rawValue: method) {
257 | handleEvent(event, topic: topic, decrypted: decrypted)
258 | }
259 | } catch let error {
260 | print(error)
261 | }
262 | }
263 | }
264 |
--------------------------------------------------------------------------------
/WalletConnect/WCSession.swift:
--------------------------------------------------------------------------------
1 | //
2 | // WCSession.swift
3 | // WalletConnect
4 | //
5 | // Created by Tao Xu on 3/29/19.
6 | // Copyright © 2019 Trust. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CryptoSwift
11 |
12 | public struct WCSession {
13 | public let topic: String
14 | public let version: String
15 | public let bridge: URL
16 | public let key: Data
17 |
18 | public static func from(string: String) -> WCSession? {
19 | guard string .hasPrefix("wc:") else {
20 | return nil
21 | }
22 |
23 | let urlString = string.replacingOccurrences(of: "wc:", with: "wc://")
24 | guard let url = URL(string: urlString),
25 | let topic = url.user,
26 | let version = url.host,
27 | let components = NSURLComponents(url: url, resolvingAgainstBaseURL: false) else {
28 | return nil
29 | }
30 |
31 | var dicts = [String: String]()
32 | for query in components.queryItems ?? [] {
33 | if let value = query.value {
34 | dicts[query.name] = value
35 | }
36 | }
37 | guard let bridge = dicts["bridge"],
38 | let bridgeUrl = URL(string: bridge),
39 | let key = dicts["key"] else {
40 | return nil
41 | }
42 |
43 | return WCSession(topic: topic, version: version, bridge: bridgeUrl, key: Data(hex: key))
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/_Pods.xcodeproj:
--------------------------------------------------------------------------------
1 | Example/Pods/Pods.xcodeproj
--------------------------------------------------------------------------------