├── .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 --------------------------------------------------------------------------------