From 0d7f62432b03be8eb338941b995c09aeb7e3e673 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Wed, 19 Jan 2022 12:38:53 +0100 Subject: [PATCH 01/19] split app into two targets --- Example/DApp/ActivePairingItem.swift | 6 + Example/DApp/ActiveSessionCell.swift | 78 +++++++ Example/DApp/AppDelegate.swift | 27 +++ .../AccentColor.colorset/Contents.json | 11 + .../AppIcon.appiconset/Contents.json | 98 +++++++++ Example/DApp/Assets.xcassets/Contents.json | 6 + .../DApp/Base.lproj/LaunchScreen.storyboard | 25 +++ Example/DApp/Info.plist | 64 ++++++ .../Proposer => DApp}/ProposerView.swift | 0 .../ProposerViewController.swift | 6 +- Example/DApp/SceneDelegate.swift | 55 +++++ Example/DApp/ViewController.swift | 19 ++ Example/ExampleApp.xcodeproj/project.pbxproj | 200 ++++++++++++++++-- .../{Responder => }/ActiveSessionCell.swift | 0 .../{Responder => }/ActiveSessionItem.swift | 0 15 files changed, 576 insertions(+), 19 deletions(-) create mode 100644 Example/DApp/ActivePairingItem.swift create mode 100644 Example/DApp/ActiveSessionCell.swift create mode 100644 Example/DApp/AppDelegate.swift create mode 100644 Example/DApp/Assets.xcassets/AccentColor.colorset/Contents.json create mode 100644 Example/DApp/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 Example/DApp/Assets.xcassets/Contents.json create mode 100644 Example/DApp/Base.lproj/LaunchScreen.storyboard create mode 100644 Example/DApp/Info.plist rename Example/{ExampleApp/Proposer => DApp}/ProposerView.swift (100%) rename Example/{ExampleApp/Proposer => DApp}/ProposerViewController.swift (98%) create mode 100644 Example/DApp/SceneDelegate.swift create mode 100644 Example/DApp/ViewController.swift rename Example/ExampleApp/{Responder => }/ActiveSessionCell.swift (100%) rename Example/ExampleApp/{Responder => }/ActiveSessionItem.swift (100%) diff --git a/Example/DApp/ActivePairingItem.swift b/Example/DApp/ActivePairingItem.swift new file mode 100644 index 000000000..7c50aadb5 --- /dev/null +++ b/Example/DApp/ActivePairingItem.swift @@ -0,0 +1,6 @@ +struct ActivePairingItem { + let dappName: String + let dappURL: String + let iconURL: String + let topic: String +} diff --git a/Example/DApp/ActiveSessionCell.swift b/Example/DApp/ActiveSessionCell.swift new file mode 100644 index 000000000..8f52a55ec --- /dev/null +++ b/Example/DApp/ActiveSessionCell.swift @@ -0,0 +1,78 @@ +import UIKit + +final class ActiveSessionCell: UITableViewCell { + + var item: ActivePairingItem? { + didSet { + if let item = item { + show(item) + } + } + } + + private let iconView: UIImageView = { + let imageView = UIImageView() + imageView.contentMode = .scaleAspectFit + imageView.layer.cornerRadius = 20 + return imageView + }() + + private let titleLabel: UILabel = { + let label = UILabel() + label.setContentHuggingPriority(.defaultHigh, for: .vertical) + return label + }() + + private let subtitleLabel: UILabel = { + let label = UILabel() + label.font = UIFont.preferredFont(forTextStyle: .caption1) + label.textColor = .secondaryLabel + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + accessoryType = .disclosureIndicator + selectionStyle = .none + + contentView.addSubview(iconView) + contentView.addSubview(titleLabel) + contentView.addSubview(subtitleLabel) + + contentView.subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } + + NSLayoutConstraint.activate([ + iconView.heightAnchor.constraint(equalToConstant: 40), + iconView.heightAnchor.constraint(equalTo: iconView.widthAnchor), + iconView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), + iconView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20), + + titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10), + titleLabel.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: 16), + titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16), + + subtitleLabel.topAnchor.constraint(equalTo: titleLabel.lastBaselineAnchor, constant: 6), + subtitleLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor), + subtitleLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor), + subtitleLabel.lastBaselineAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -12) + ]) + } + + private func show(_ item: ActivePairingItem) { + titleLabel.text = item.dappName + subtitleLabel.text = item.dappURL + iconView.image = nil + guard let iconURL = URL(string: item.iconURL) else { return } + DispatchQueue.global().async { + if let imageData = try? Data(contentsOf: iconURL) { + DispatchQueue.main.async { [weak self] in + self?.iconView.image = UIImage(data: imageData) + } + } + } + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Example/DApp/AppDelegate.swift b/Example/DApp/AppDelegate.swift new file mode 100644 index 000000000..7256ad23d --- /dev/null +++ b/Example/DApp/AppDelegate.swift @@ -0,0 +1,27 @@ + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Example/DApp/Assets.xcassets/AccentColor.colorset/Contents.json b/Example/DApp/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/Example/DApp/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/DApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/DApp/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..9221b9bb1 --- /dev/null +++ b/Example/DApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/DApp/Assets.xcassets/Contents.json b/Example/DApp/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/Example/DApp/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/DApp/Base.lproj/LaunchScreen.storyboard b/Example/DApp/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000..865e9329f --- /dev/null +++ b/Example/DApp/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/DApp/Info.plist b/Example/DApp/Info.plist new file mode 100644 index 000000000..9c3b929aa --- /dev/null +++ b/Example/DApp/Info.plist @@ -0,0 +1,64 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Demo App + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + ITSAppUsesNonExemptEncryption + + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Example/ExampleApp/Proposer/ProposerView.swift b/Example/DApp/ProposerView.swift similarity index 100% rename from Example/ExampleApp/Proposer/ProposerView.swift rename to Example/DApp/ProposerView.swift diff --git a/Example/ExampleApp/Proposer/ProposerViewController.swift b/Example/DApp/ProposerViewController.swift similarity index 98% rename from Example/ExampleApp/Proposer/ProposerViewController.swift rename to Example/DApp/ProposerViewController.swift index 65a3fee8a..730efd774 100644 --- a/Example/ExampleApp/Proposer/ProposerViewController.swift +++ b/Example/DApp/ProposerViewController.swift @@ -18,7 +18,7 @@ final class ProposerViewController: UIViewController { ) }() - var activeItems: [ActiveSessionItem] = [] + var activeItems: [ActivePairingItem] = [] private var currentURI: String? private let proposerView: ProposerView = { @@ -159,9 +159,9 @@ extension ProposerViewController: WalletConnectClientDelegate { func didSettle(pairing: Pairing) { print("[PROPOSER] WC: Did settle pairing") let settledPairings = client.getSettledPairings() - let activePairings = settledPairings.map { pairing -> ActiveSessionItem in + let activePairings = settledPairings.map { pairing -> ActivePairingItem in let app = pairing.peer - return ActiveSessionItem( + return ActivePairingItem( dappName: app?.name ?? "", dappURL: app?.url ?? "", iconURL: app?.icons?.first ?? "", diff --git a/Example/DApp/SceneDelegate.swift b/Example/DApp/SceneDelegate.swift new file mode 100644 index 000000000..bf65db1b6 --- /dev/null +++ b/Example/DApp/SceneDelegate.swift @@ -0,0 +1,55 @@ +// +// SceneDelegate.swift +// DApp +// +// Created by Admin on 19/01/2022. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let windowScene = (scene as? UIWindowScene) else { return } + window = UIWindow(windowScene: windowScene) + window?.rootViewController = UINavigationController(rootViewController: ProposerViewController()) + window?.makeKeyAndVisible() + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Example/DApp/ViewController.swift b/Example/DApp/ViewController.swift new file mode 100644 index 000000000..028a268db --- /dev/null +++ b/Example/DApp/ViewController.swift @@ -0,0 +1,19 @@ +// +// ViewController.swift +// DApp +// +// Created by Admin on 19/01/2022. +// + +import UIKit + +class ViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + +} + diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index dc0b3c745..fed2a8c4d 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -7,8 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 7603D74D2703429A00DD27A2 /* ProposerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7603D74C2703429A00DD27A2 /* ProposerView.swift */; }; - 761C649A26FB7ABB004239D1 /* ProposerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C649926FB7ABB004239D1 /* ProposerViewController.swift */; }; 761C649C26FB7B7F004239D1 /* ResponderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C649B26FB7B7F004239D1 /* ResponderViewController.swift */; }; 761C649E26FB7FD7004239D1 /* SessionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C649D26FB7FD7004239D1 /* SessionViewController.swift */; }; 761C64A326FB83CE004239D1 /* SessionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C64A226FB83CE004239D1 /* SessionView.swift */; }; @@ -28,6 +26,17 @@ 8460DCFC274F98A10081F94C /* RequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460DCFB274F98A10081F94C /* RequestViewController.swift */; }; 8460DD002750D6F50081F94C /* SessionDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460DCFF2750D6F50081F94C /* SessionDetailsViewController.swift */; }; 8460DD022750D7020081F94C /* SessionDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460DD012750D7020081F94C /* SessionDetailsView.swift */; }; + 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE641E27981DED00142511 /* AppDelegate.swift */; }; + 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE642027981DED00142511 /* SceneDelegate.swift */; }; + 84CE642327981DED00142511 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE642227981DED00142511 /* ViewController.swift */; }; + 84CE642827981DF000142511 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642727981DF000142511 /* Assets.xcassets */; }; + 84CE642B27981DF000142511 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642927981DF000142511 /* LaunchScreen.storyboard */; }; + 84CE6430279820F600142511 /* ProposerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C649926FB7ABB004239D1 /* ProposerViewController.swift */; }; + 84CE6431279820F600142511 /* ProposerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7603D74C2703429A00DD27A2 /* ProposerView.swift */; }; + 84CE64352798222E00142511 /* ActiveSessionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE64332798222400142511 /* ActiveSessionCell.swift */; }; + 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE64362798224900142511 /* ActivePairingItem.swift */; }; + 84CE64392798228D00142511 /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE64382798228D00142511 /* Web3 */; }; + 84CE643B2798229100142511 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE643A2798229100142511 /* WalletConnect */; }; 84F568C2279582D200D0A289 /* Signer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C1279582D200D0A289 /* Signer.swift */; }; 84F568C42795832A00D0A289 /* EthereumTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C32795832A00D0A289 /* EthereumTransaction.swift */; }; /* End PBXBuildFile section */ @@ -68,6 +77,15 @@ 8460DCFB274F98A10081F94C /* RequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestViewController.swift; sourceTree = ""; }; 8460DCFF2750D6F50081F94C /* SessionDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailsViewController.swift; sourceTree = ""; }; 8460DD012750D7020081F94C /* SessionDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailsView.swift; sourceTree = ""; }; + 84CE641C27981DED00142511 /* DApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 84CE641E27981DED00142511 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 84CE642027981DED00142511 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 84CE642227981DED00142511 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 84CE642727981DF000142511 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 84CE642A27981DF000142511 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 84CE642C27981DF000142511 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 84CE64332798222400142511 /* ActiveSessionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ActiveSessionCell.swift; path = DApp/ActiveSessionCell.swift; sourceTree = SOURCE_ROOT; }; + 84CE64362798224900142511 /* ActivePairingItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivePairingItem.swift; sourceTree = ""; }; 84F568C1279582D200D0A289 /* Signer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signer.swift; sourceTree = ""; }; 84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -89,6 +107,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 84CE641927981DED00142511 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 84CE643B2798229100142511 /* WalletConnect in Frameworks */, + 84CE64392798228D00142511 /* Web3 in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -100,8 +127,6 @@ 84F568C1279582D200D0A289 /* Signer.swift */, 84494387278D9C1B00CC26BB /* UIAlertController.swift */, 76744CF426FDFB6B00B77ED9 /* ResponderView.swift */, - 76744CF826FE4D7400B77ED9 /* ActiveSessionCell.swift */, - 76744CF626FE4D5400B77ED9 /* ActiveSessionItem.swift */, 764E1D5926F8DF1B00A1FB15 /* ScannerViewController.swift */, 761C64A426FCB08B004239D1 /* SessionProposal */, 8460DCFD274F98A90081F94C /* Request */, @@ -109,15 +134,6 @@ path = Responder; sourceTree = ""; }; - 761C64A126FB838D004239D1 /* Proposer */ = { - isa = PBXGroup; - children = ( - 761C649926FB7ABB004239D1 /* ProposerViewController.swift */, - 7603D74C2703429A00DD27A2 /* ProposerView.swift */, - ); - path = Proposer; - sourceTree = ""; - }; 761C64A426FCB08B004239D1 /* SessionProposal */ = { isa = PBXGroup; children = ( @@ -133,6 +149,7 @@ children = ( 764E1D3E26F8D3FC00A1FB15 /* ExampleApp */, 845B30ED27859686002E4094 /* ExampleAppTests */, + 84CE641D27981DED00142511 /* DApp */, 764E1D3D26F8D3FC00A1FB15 /* Products */, 764E1D5326F8DAC800A1FB15 /* Frameworks */, 764E1D5626F8DB6000A1FB15 /* WalletConnectSwiftV2 */, @@ -144,6 +161,7 @@ children = ( 764E1D3C26F8D3FC00A1FB15 /* ExampleApp.app */, 845B30EC27859686002E4094 /* ExampleAppTests.xctest */, + 84CE641C27981DED00142511 /* DApp.app */, ); name = Products; sourceTree = ""; @@ -153,9 +171,10 @@ children = ( 764E1D3F26F8D3FC00A1FB15 /* AppDelegate.swift */, 764E1D4126F8D3FC00A1FB15 /* SceneDelegate.swift */, + 76744CF826FE4D7400B77ED9 /* ActiveSessionCell.swift */, + 76744CF626FE4D5400B77ED9 /* ActiveSessionItem.swift */, 8460DCFE2750D6DF0081F94C /* SessionDetails */, 761C64A026FB8387004239D1 /* Responder */, - 761C64A126FB838D004239D1 /* Proposer */, 764E1D4826F8D3FE00A1FB15 /* Assets.xcassets */, 764E1D4A26F8D3FE00A1FB15 /* LaunchScreen.storyboard */, 764E1D4D26F8D3FE00A1FB15 /* Info.plist */, @@ -197,6 +216,23 @@ path = SessionDetails; sourceTree = ""; }; + 84CE641D27981DED00142511 /* DApp */ = { + isa = PBXGroup; + children = ( + 84CE64362798224900142511 /* ActivePairingItem.swift */, + 84CE64332798222400142511 /* ActiveSessionCell.swift */, + 84CE641E27981DED00142511 /* AppDelegate.swift */, + 84CE642027981DED00142511 /* SceneDelegate.swift */, + 84CE642227981DED00142511 /* ViewController.swift */, + 761C649926FB7ABB004239D1 /* ProposerViewController.swift */, + 7603D74C2703429A00DD27A2 /* ProposerView.swift */, + 84CE642727981DF000142511 /* Assets.xcassets */, + 84CE642927981DF000142511 /* LaunchScreen.storyboard */, + 84CE642C27981DF000142511 /* Info.plist */, + ); + path = DApp; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -239,6 +275,27 @@ productReference = 845B30EC27859686002E4094 /* ExampleAppTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 84CE641B27981DED00142511 /* DApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 84CE642F27981DF000142511 /* Build configuration list for PBXNativeTarget "DApp" */; + buildPhases = ( + 84CE641827981DED00142511 /* Sources */, + 84CE641927981DED00142511 /* Frameworks */, + 84CE641A27981DED00142511 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = DApp; + packageProductDependencies = ( + 84CE64382798228D00142511 /* Web3 */, + 84CE643A2798229100142511 /* WalletConnect */, + ); + productName = DApp; + productReference = 84CE641C27981DED00142511 /* DApp.app */; + productType = "com.apple.product-type.application"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -255,6 +312,9 @@ CreatedOnToolsVersion = 13.2; TestTargetID = 764E1D3B26F8D3FC00A1FB15; }; + 84CE641B27981DED00142511 = { + CreatedOnToolsVersion = 13.2; + }; }; }; buildConfigurationList = 764E1D3726F8D3FC00A1FB15 /* Build configuration list for PBXProject "ExampleApp" */; @@ -275,6 +335,7 @@ targets = ( 764E1D3B26F8D3FC00A1FB15 /* ExampleApp */, 845B30EB27859686002E4094 /* ExampleAppTests */, + 84CE641B27981DED00142511 /* DApp */, ); }; /* End PBXProject section */ @@ -296,6 +357,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 84CE641A27981DED00142511 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84CE642B27981DF000142511 /* LaunchScreen.storyboard in Resources */, + 84CE642827981DF000142511 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -306,7 +376,6 @@ 761C64A326FB83CE004239D1 /* SessionView.swift in Sources */, 8460DCFC274F98A10081F94C /* RequestViewController.swift in Sources */, 76744CF526FDFB6B00B77ED9 /* ResponderView.swift in Sources */, - 761C649A26FB7ABB004239D1 /* ProposerViewController.swift in Sources */, 8460DD002750D6F50081F94C /* SessionDetailsViewController.swift in Sources */, 76744CF926FE4D7400B77ED9 /* ActiveSessionCell.swift in Sources */, 764E1D4026F8D3FC00A1FB15 /* AppDelegate.swift in Sources */, @@ -317,7 +386,6 @@ 764E1D4226F8D3FC00A1FB15 /* SceneDelegate.swift in Sources */, 84F568C2279582D200D0A289 /* Signer.swift in Sources */, 8460DD022750D7020081F94C /* SessionDetailsView.swift in Sources */, - 7603D74D2703429A00DD27A2 /* ProposerView.swift in Sources */, 764E1D5A26F8DF1B00A1FB15 /* ScannerViewController.swift in Sources */, 84494388278D9C1B00CC26BB /* UIAlertController.swift in Sources */, 84F568C42795832A00D0A289 /* EthereumTransaction.swift in Sources */, @@ -332,6 +400,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 84CE641827981DED00142511 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 84CE6430279820F600142511 /* ProposerViewController.swift in Sources */, + 84CE642327981DED00142511 /* ViewController.swift in Sources */, + 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */, + 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */, + 84CE64352798222E00142511 /* ActiveSessionCell.swift in Sources */, + 84CE6431279820F600142511 /* ProposerView.swift in Sources */, + 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -351,6 +433,14 @@ name = LaunchScreen.storyboard; sourceTree = ""; }; + 84CE642927981DF000142511 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 84CE642A27981DF000142511 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -558,6 +648,66 @@ }; name = Release; }; + 84CE642D27981DF000142511 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W5R8AG9K22; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = DApp/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.DApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 84CE642E27981DF000142511 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = W5R8AG9K22; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = DApp/Info.plist; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.walletconnect.DApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -588,6 +738,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 84CE642F27981DF000142511 /* Build configuration list for PBXNativeTarget "DApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 84CE642D27981DF000142511 /* Debug */, + 84CE642E27981DF000142511 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ @@ -611,6 +770,15 @@ package = 8449439F278EC49700CC26BB /* XCRemoteSwiftPackageReference "Web3" */; productName = Web3; }; + 84CE64382798228D00142511 /* Web3 */ = { + isa = XCSwiftPackageProductDependency; + package = 8449439F278EC49700CC26BB /* XCRemoteSwiftPackageReference "Web3" */; + productName = Web3; + }; + 84CE643A2798229100142511 /* WalletConnect */ = { + isa = XCSwiftPackageProductDependency; + productName = WalletConnect; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 764E1D3426F8D3FC00A1FB15 /* Project object */; diff --git a/Example/ExampleApp/Responder/ActiveSessionCell.swift b/Example/ExampleApp/ActiveSessionCell.swift similarity index 100% rename from Example/ExampleApp/Responder/ActiveSessionCell.swift rename to Example/ExampleApp/ActiveSessionCell.swift diff --git a/Example/ExampleApp/Responder/ActiveSessionItem.swift b/Example/ExampleApp/ActiveSessionItem.swift similarity index 100% rename from Example/ExampleApp/Responder/ActiveSessionItem.swift rename to Example/ExampleApp/ActiveSessionItem.swift From a0974d711164a145778423ebaba805a013873324 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 20 Jan 2022 09:09:53 +0100 Subject: [PATCH 02/19] savepoint --- ...sionCell.swift => ActivePairingCell.swift} | 6 +- Example/DApp/ActivePairingItem.swift | 4 +- Example/DApp/ConnectViewController.swift | 98 +++++++++++++++++++ Example/DApp/ProposerView.swift | 35 +------ Example/DApp/ProposerViewController.swift | 50 +++------- Example/ExampleApp.xcodeproj/project.pbxproj | 12 ++- .../Responder/ResponderViewController.swift | 2 +- Example/ExampleApp/SceneDelegate.swift | 2 - .../WalletConnect/WalletConnectClient.swift | 1 + 9 files changed, 129 insertions(+), 81 deletions(-) rename Example/DApp/{ActiveSessionCell.swift => ActivePairingCell.swift} (95%) create mode 100644 Example/DApp/ConnectViewController.swift diff --git a/Example/DApp/ActiveSessionCell.swift b/Example/DApp/ActivePairingCell.swift similarity index 95% rename from Example/DApp/ActiveSessionCell.swift rename to Example/DApp/ActivePairingCell.swift index 8f52a55ec..ca68cff75 100644 --- a/Example/DApp/ActiveSessionCell.swift +++ b/Example/DApp/ActivePairingCell.swift @@ -1,6 +1,6 @@ import UIKit -final class ActiveSessionCell: UITableViewCell { +final class ActivePairingCell: UITableViewCell { var item: ActivePairingItem? { didSet { @@ -59,8 +59,8 @@ final class ActiveSessionCell: UITableViewCell { } private func show(_ item: ActivePairingItem) { - titleLabel.text = item.dappName - subtitleLabel.text = item.dappURL + titleLabel.text = item.peerName + subtitleLabel.text = item.peerURL iconView.image = nil guard let iconURL = URL(string: item.iconURL) else { return } DispatchQueue.global().async { diff --git a/Example/DApp/ActivePairingItem.swift b/Example/DApp/ActivePairingItem.swift index 7c50aadb5..96899b9d7 100644 --- a/Example/DApp/ActivePairingItem.swift +++ b/Example/DApp/ActivePairingItem.swift @@ -1,6 +1,6 @@ struct ActivePairingItem { - let dappName: String - let dappURL: String + let peerName: String + let peerURL: String let iconURL: String let topic: String } diff --git a/Example/DApp/ConnectViewController.swift b/Example/DApp/ConnectViewController.swift new file mode 100644 index 000000000..ed77a9abb --- /dev/null +++ b/Example/DApp/ConnectViewController.swift @@ -0,0 +1,98 @@ + +import Foundation +import UIKit + +class ConnectViewController: UIViewController { + let uriString: String + init(uri: String) { + self.uriString = uri + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private let connectView: ConnectView = { + ConnectView() + }() + + override func loadView() { + view = connectView + } + + override func viewDidLoad() { + super.viewDidLoad() + DispatchQueue.global().async { [unowned self] in + if let qrImage = generateQRCode(from: uriString) { + DispatchQueue.main.async { + connectView.qrCodeView.image = qrImage + connectView.copyButton.isHidden = false + } + } + } + connectView.copyButton.addTarget(self, action: #selector(copyURI), for: .touchUpInside) + connectView.copyButton.isHidden = true + } + + + @objc func copyURI() { + UIPasteboard.general.string = uriString + } + + + private func generateQRCode(from string: String) -> UIImage? { + let data = string.data(using: .ascii) + if let filter = CIFilter(name: "CIQRCodeGenerator") { + filter.setValue(data, forKey: "inputMessage") + if let output = filter.outputImage { + return UIImage(ciImage: output) + } + } + return nil + } +} + +final class ConnectView: UIView { + let qrCodeView: UIImageView = { + let imageView = UIImageView() + imageView.contentMode = .scaleAspectFit + return imageView + }() + + let copyButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("Copy", for: .normal) + button.setImage(UIImage(systemName: "doc.on.doc"), for: .normal) + button.titleLabel?.font = UIFont.systemFont(ofSize: 17.0, weight: .semibold) + button.backgroundColor = .systemBlue + button.tintColor = .white + button.layer.cornerRadius = 8 + return button + }() + + override init(frame: CGRect) { + super.init(frame: frame) + backgroundColor = .systemBackground + addSubview(qrCodeView) + addSubview(copyButton) + + subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } + + NSLayoutConstraint.activate([ + qrCodeView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 64), + qrCodeView.centerXAnchor.constraint(equalTo: centerXAnchor), + qrCodeView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.6), + qrCodeView.widthAnchor.constraint(equalTo: qrCodeView.heightAnchor), + + copyButton.topAnchor.constraint(equalTo: qrCodeView.bottomAnchor, constant: 16), + copyButton.centerXAnchor.constraint(equalTo: centerXAnchor), + copyButton.widthAnchor.constraint(equalTo: qrCodeView.widthAnchor), + copyButton.heightAnchor.constraint(equalToConstant: 44), + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Example/DApp/ProposerView.swift b/Example/DApp/ProposerView.swift index 687b4d2de..626d7e41b 100644 --- a/Example/DApp/ProposerView.swift +++ b/Example/DApp/ProposerView.swift @@ -1,53 +1,22 @@ import UIKit final class ProposerView: UIView { - - let qrCodeView: UIImageView = { - let imageView = UIImageView() - imageView.contentMode = .scaleAspectFit - return imageView - }() - - let copyButton: UIButton = { - let button = UIButton(type: .system) - button.setTitle("Copy", for: .normal) - button.setImage(UIImage(systemName: "doc.on.doc"), for: .normal) - button.titleLabel?.font = UIFont.systemFont(ofSize: 17.0, weight: .semibold) - button.backgroundColor = .systemBlue - button.tintColor = .white - button.layer.cornerRadius = 8 - return button - }() - let tableView: UITableView = { let tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.backgroundColor = .tertiarySystemBackground - tableView.register(ActiveSessionCell.self, forCellReuseIdentifier: "sessionCell") + tableView.register(ActivePairingCell.self, forCellReuseIdentifier: "sessionCell") return tableView }() override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .systemBackground - - addSubview(qrCodeView) - addSubview(copyButton) addSubview(tableView) subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } NSLayoutConstraint.activate([ - qrCodeView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 64), - qrCodeView.centerXAnchor.constraint(equalTo: centerXAnchor), - qrCodeView.widthAnchor.constraint(equalTo: widthAnchor, multiplier: 0.6), - qrCodeView.widthAnchor.constraint(equalTo: qrCodeView.heightAnchor), - - copyButton.topAnchor.constraint(equalTo: qrCodeView.bottomAnchor, constant: 16), - copyButton.centerXAnchor.constraint(equalTo: centerXAnchor), - copyButton.widthAnchor.constraint(equalTo: qrCodeView.widthAnchor), - copyButton.heightAnchor.constraint(equalToConstant: 44), - - tableView.topAnchor.constraint(equalTo: copyButton.bottomAnchor, constant: 16), + tableView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 16), tableView.leadingAnchor.constraint(equalTo: leadingAnchor), tableView.trailingAnchor.constraint(equalTo: trailingAnchor), tableView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor) diff --git a/Example/DApp/ProposerViewController.swift b/Example/DApp/ProposerViewController.swift index 730efd774..a3b8e3420 100644 --- a/Example/DApp/ProposerViewController.swift +++ b/Example/DApp/ProposerViewController.swift @@ -39,18 +39,11 @@ final class ProposerViewController: UIViewController { target: self, action: #selector(connect) ) - - proposerView.copyButton.addTarget(self, action: #selector(copyURI), for: .touchUpInside) - proposerView.copyButton.isHidden = true - proposerView.tableView.dataSource = self proposerView.tableView.delegate = self client.delegate = self - } - - @objc func copyURI() { - UIPasteboard.general.string = currentURI + client.logger.setLogging(level: .debug) } @objc @@ -63,35 +56,20 @@ final class ProposerViewController: UIViewController { ) do { if let uri = try client.connect(sessionPermissions: permissions) { - showQRCode(uriString: uri) + showConnectScreen(uriString: uri) } } catch { print("[PROPOSER] Pairing connect error: \(error)") } } - private func showQRCode(uriString: String) { - currentURI = uriString - DispatchQueue.global().async { [weak self] in - if let qrImage = self?.generateQRCode(from: uriString) { - DispatchQueue.main.async { - self?.proposerView.qrCodeView.image = qrImage - self?.proposerView.copyButton.isHidden = false - } - } - } - } - - private func generateQRCode(from string: String) -> UIImage? { - let data = string.data(using: .ascii) - if let filter = CIFilter(name: "CIQRCodeGenerator") { - filter.setValue(data, forKey: "inputMessage") - if let output = filter.outputImage { - return UIImage(ciImage: output) - } + private func showConnectScreen(uriString: String) { + DispatchQueue.main.async { [unowned self] in + let vc = ConnectViewController(uri: uriString) + present(vc, animated: true, completion: nil) } - return nil } + } extension ProposerViewController: UITableViewDataSource, UITableViewDelegate { @@ -101,13 +79,15 @@ extension ProposerViewController: UITableViewDataSource, UITableViewDelegate { } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "sessionCell", for: indexPath) as! ActiveSessionCell + let cell = tableView.dequeueReusableCell(withIdentifier: "sessionCell", for: indexPath) as! ActivePairingCell cell.item = activeItems[indexPath.row] return cell } func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { + let item = activeItems[indexPath.row] + client.disconnect(topic: item.topic, reason: Reason(code: 0, message: "disconnect")) activeItems.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .automatic) } @@ -160,18 +140,16 @@ extension ProposerViewController: WalletConnectClientDelegate { print("[PROPOSER] WC: Did settle pairing") let settledPairings = client.getSettledPairings() let activePairings = settledPairings.map { pairing -> ActivePairingItem in - let app = pairing.peer + let peer = pairing.peer return ActivePairingItem( - dappName: app?.name ?? "", - dappURL: app?.url ?? "", - iconURL: app?.icons?.first ?? "", + peerName: peer?.name ?? "", + peerURL: peer?.url ?? "", + iconURL: peer?.icons?.first ?? "", topic: pairing.topic) } DispatchQueue.main.async { self.activeItems = activePairings self.proposerView.tableView.reloadData() - self.proposerView.qrCodeView.image = nil - self.proposerView.copyButton.isHidden = true } } diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index fed2a8c4d..e0530973b 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -33,10 +33,11 @@ 84CE642B27981DF000142511 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642927981DF000142511 /* LaunchScreen.storyboard */; }; 84CE6430279820F600142511 /* ProposerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C649926FB7ABB004239D1 /* ProposerViewController.swift */; }; 84CE6431279820F600142511 /* ProposerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7603D74C2703429A00DD27A2 /* ProposerView.swift */; }; - 84CE64352798222E00142511 /* ActiveSessionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE64332798222400142511 /* ActiveSessionCell.swift */; }; + 84CE64352798222E00142511 /* ActivePairingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE64332798222400142511 /* ActivePairingCell.swift */; }; 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE64362798224900142511 /* ActivePairingItem.swift */; }; 84CE64392798228D00142511 /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE64382798228D00142511 /* Web3 */; }; 84CE643B2798229100142511 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE643A2798229100142511 /* WalletConnect */; }; + 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE643C2798322600142511 /* ConnectViewController.swift */; }; 84F568C2279582D200D0A289 /* Signer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C1279582D200D0A289 /* Signer.swift */; }; 84F568C42795832A00D0A289 /* EthereumTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C32795832A00D0A289 /* EthereumTransaction.swift */; }; /* End PBXBuildFile section */ @@ -84,8 +85,9 @@ 84CE642727981DF000142511 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 84CE642A27981DF000142511 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 84CE642C27981DF000142511 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 84CE64332798222400142511 /* ActiveSessionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ActiveSessionCell.swift; path = DApp/ActiveSessionCell.swift; sourceTree = SOURCE_ROOT; }; + 84CE64332798222400142511 /* ActivePairingCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ActivePairingCell.swift; path = DApp/ActivePairingCell.swift; sourceTree = SOURCE_ROOT; }; 84CE64362798224900142511 /* ActivePairingItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivePairingItem.swift; sourceTree = ""; }; + 84CE643C2798322600142511 /* ConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = ""; }; 84F568C1279582D200D0A289 /* Signer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signer.swift; sourceTree = ""; }; 84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -220,11 +222,12 @@ isa = PBXGroup; children = ( 84CE64362798224900142511 /* ActivePairingItem.swift */, - 84CE64332798222400142511 /* ActiveSessionCell.swift */, + 84CE64332798222400142511 /* ActivePairingCell.swift */, 84CE641E27981DED00142511 /* AppDelegate.swift */, 84CE642027981DED00142511 /* SceneDelegate.swift */, 84CE642227981DED00142511 /* ViewController.swift */, 761C649926FB7ABB004239D1 /* ProposerViewController.swift */, + 84CE643C2798322600142511 /* ConnectViewController.swift */, 7603D74C2703429A00DD27A2 /* ProposerView.swift */, 84CE642727981DF000142511 /* Assets.xcassets */, 84CE642927981DF000142511 /* LaunchScreen.storyboard */, @@ -408,9 +411,10 @@ 84CE642327981DED00142511 /* ViewController.swift in Sources */, 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */, 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */, - 84CE64352798222E00142511 /* ActiveSessionCell.swift in Sources */, + 84CE64352798222E00142511 /* ActivePairingCell.swift in Sources */, 84CE6431279820F600142511 /* ProposerView.swift in Sources */, 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */, + 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/ExampleApp/Responder/ResponderViewController.swift b/Example/ExampleApp/Responder/ResponderViewController.swift index c5049becd..855520c35 100644 --- a/Example/ExampleApp/Responder/ResponderViewController.swift +++ b/Example/ExampleApp/Responder/ResponderViewController.swift @@ -43,6 +43,7 @@ final class ResponderViewController: UIViewController { let settledSessions = client.getSettledSessions() sessionItems = getActiveSessionItem(for: settledSessions) client.delegate = self + client.logger.setLogging(level: .debug) } @objc @@ -119,7 +120,6 @@ extension ResponderViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { if editingStyle == .delete { let item = sessionItems[indexPath.row] -// let deleteParams = SessionType.DeleteParams(topic: item.topic, reason: SessionType.Reason(code: 0, message: "disconnect")) client.disconnect(topic: item.topic, reason: Reason(code: 0, message: "disconnect")) sessionItems.remove(at: indexPath.row) tableView.deleteRows(at: [indexPath], with: .automatic) diff --git a/Example/ExampleApp/SceneDelegate.swift b/Example/ExampleApp/SceneDelegate.swift index 3cdd41306..19514b446 100644 --- a/Example/ExampleApp/SceneDelegate.swift +++ b/Example/ExampleApp/SceneDelegate.swift @@ -17,8 +17,6 @@ extension UITabBarController { static func createExampleApp() -> UITabBarController { let responderController = UINavigationController(rootViewController: ResponderViewController()) responderController.tabBarItem = UITabBarItem(title: "Wallet", image: UIImage(systemName: "dollarsign.circle"), selectedImage: nil) - let proposerController = UINavigationController(rootViewController: ProposerViewController()) - proposerController.tabBarItem = UITabBarItem(title: "Dapp", image: UIImage(systemName: "appclip"), selectedImage: nil) let tabBarController = UITabBarController() tabBarController.viewControllers = [responderController] return tabBarController diff --git a/Sources/WalletConnect/WalletConnectClient.swift b/Sources/WalletConnect/WalletConnectClient.swift index 9038789ad..c52142178 100644 --- a/Sources/WalletConnect/WalletConnectClient.swift +++ b/Sources/WalletConnect/WalletConnectClient.swift @@ -224,6 +224,7 @@ public final class WalletConnectClient { pairingEngine.getSettledPairings() } + /// - Returns: Pending requests received with wc_sessionPayload public func getPendingRequests() -> [Request] { history.getPending() .filter{$0.request.method == .sessionPayload} From 95291fa0b9b0b955615ec6a9dc7a66d3554c802d Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 20 Jan 2022 12:00:37 +0100 Subject: [PATCH 03/19] register background task --- Example/DApp/ProposerViewController.swift | 1 + .../WalletConnect/Engine/PairingEngine.swift | 3 ++- .../WalletConnect/WalletConnectClient.swift | 27 +++++++++++-------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Example/DApp/ProposerViewController.swift b/Example/DApp/ProposerViewController.swift index a3b8e3420..fb4746bbb 100644 --- a/Example/DApp/ProposerViewController.swift +++ b/Example/DApp/ProposerViewController.swift @@ -44,6 +44,7 @@ final class ProposerViewController: UIViewController { client.delegate = self client.logger.setLogging(level: .debug) + } @objc diff --git a/Sources/WalletConnect/Engine/PairingEngine.swift b/Sources/WalletConnect/Engine/PairingEngine.swift index 56d85e036..bff5522e0 100644 --- a/Sources/WalletConnect/Engine/PairingEngine.swift +++ b/Sources/WalletConnect/Engine/PairingEngine.swift @@ -2,6 +2,7 @@ import Foundation import Combine import WalletConnectUtils + final class PairingEngine { var onApprovalAcknowledgement: ((Pairing) -> Void)? @@ -163,7 +164,7 @@ final class PairingEngine { } } } - + private func setUpWCRequestHandling() { wcSubscriber.onReceivePayload = { [unowned self] subscriptionPayload in let requestId = subscriptionPayload.wcRequest.id diff --git a/Sources/WalletConnect/WalletConnectClient.swift b/Sources/WalletConnect/WalletConnectClient.swift index c52142178..403f1a3a3 100644 --- a/Sources/WalletConnect/WalletConnectClient.swift +++ b/Sources/WalletConnect/WalletConnectClient.swift @@ -31,6 +31,7 @@ public final class WalletConnectClient { private let secureStorage: SecureStorage private let pairingQueue = DispatchQueue(label: "com.walletconnect.sdk.client.pairing", qos: .userInitiated) private let history: JsonRpcHistory + private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid // MARK: - Initializers @@ -68,8 +69,21 @@ public final class WalletConnectClient { self.sessionEngine = SessionEngine(relay: relay, crypto: crypto, subscriber: WCSubscriber(relay: relay, logger: logger), sequencesStore: sessionSequencesStore, isController: isController, metadata: metadata, logger: logger) setUpEnginesCallbacks() subscribeNotificationCenter() + registerBackgroundTask() } + func registerBackgroundTask() { + self.backgroundTaskID = UIApplication.shared.beginBackgroundTask (withName: "Finish Network Tasks") { [weak self] in + self?.endBackgroundTask() + } + } + + func endBackgroundTask() { + wakuRelay.disconnect(closeCode: .goingAway) + print("Background task ended.") + UIApplication.shared.endBackgroundTask(backgroundTaskID) + backgroundTaskID = .invalid + } deinit { unsubscribeNotificationCenter() } @@ -292,11 +306,6 @@ public final class WalletConnectClient { private func subscribeNotificationCenter() { #if os(iOS) - NotificationCenter.default.addObserver( - self, - selector: #selector(appDidEnterBackground), - name: UIApplication.didEnterBackgroundNotification, - object: nil) NotificationCenter.default.addObserver( self, selector: #selector(appWillEnterForeground), @@ -307,7 +316,6 @@ public final class WalletConnectClient { private func unsubscribeNotificationCenter() { #if os(iOS) - NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil) #endif } @@ -315,10 +323,7 @@ public final class WalletConnectClient { @objc private func appWillEnterForeground() { wakuRelay.connect() + registerBackgroundTask() } - - @objc - private func appDidEnterBackground() { - wakuRelay.disconnect(closeCode: .goingAway) - } + } From 784e398bcf90855378299fe767eaebceee6888c8 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 20 Jan 2022 12:00:37 +0100 Subject: [PATCH 04/19] register background task --- .../Proposer/ProposerViewController.swift | 1 + .../WalletConnect/Engine/PairingEngine.swift | 3 ++- .../WalletConnect/WalletConnectClient.swift | 27 +++++++++++-------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/Example/ExampleApp/Proposer/ProposerViewController.swift b/Example/ExampleApp/Proposer/ProposerViewController.swift index 65a3fee8a..511c1447e 100644 --- a/Example/ExampleApp/Proposer/ProposerViewController.swift +++ b/Example/ExampleApp/Proposer/ProposerViewController.swift @@ -47,6 +47,7 @@ final class ProposerViewController: UIViewController { proposerView.tableView.delegate = self client.delegate = self + client.logger.setLogging(level: .debug) } @objc func copyURI() { diff --git a/Sources/WalletConnect/Engine/PairingEngine.swift b/Sources/WalletConnect/Engine/PairingEngine.swift index 56d85e036..bff5522e0 100644 --- a/Sources/WalletConnect/Engine/PairingEngine.swift +++ b/Sources/WalletConnect/Engine/PairingEngine.swift @@ -2,6 +2,7 @@ import Foundation import Combine import WalletConnectUtils + final class PairingEngine { var onApprovalAcknowledgement: ((Pairing) -> Void)? @@ -163,7 +164,7 @@ final class PairingEngine { } } } - + private func setUpWCRequestHandling() { wcSubscriber.onReceivePayload = { [unowned self] subscriptionPayload in let requestId = subscriptionPayload.wcRequest.id diff --git a/Sources/WalletConnect/WalletConnectClient.swift b/Sources/WalletConnect/WalletConnectClient.swift index 9038789ad..dbb714472 100644 --- a/Sources/WalletConnect/WalletConnectClient.swift +++ b/Sources/WalletConnect/WalletConnectClient.swift @@ -31,6 +31,7 @@ public final class WalletConnectClient { private let secureStorage: SecureStorage private let pairingQueue = DispatchQueue(label: "com.walletconnect.sdk.client.pairing", qos: .userInitiated) private let history: JsonRpcHistory + private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid // MARK: - Initializers @@ -68,8 +69,21 @@ public final class WalletConnectClient { self.sessionEngine = SessionEngine(relay: relay, crypto: crypto, subscriber: WCSubscriber(relay: relay, logger: logger), sequencesStore: sessionSequencesStore, isController: isController, metadata: metadata, logger: logger) setUpEnginesCallbacks() subscribeNotificationCenter() + registerBackgroundTask() } + func registerBackgroundTask() { + self.backgroundTaskID = UIApplication.shared.beginBackgroundTask (withName: "Finish Network Tasks") { [weak self] in + self?.endBackgroundTask() + } + } + + func endBackgroundTask() { + wakuRelay.disconnect(closeCode: .goingAway) + print("Background task ended.") + UIApplication.shared.endBackgroundTask(backgroundTaskID) + backgroundTaskID = .invalid + } deinit { unsubscribeNotificationCenter() } @@ -291,11 +305,6 @@ public final class WalletConnectClient { private func subscribeNotificationCenter() { #if os(iOS) - NotificationCenter.default.addObserver( - self, - selector: #selector(appDidEnterBackground), - name: UIApplication.didEnterBackgroundNotification, - object: nil) NotificationCenter.default.addObserver( self, selector: #selector(appWillEnterForeground), @@ -306,7 +315,6 @@ public final class WalletConnectClient { private func unsubscribeNotificationCenter() { #if os(iOS) - NotificationCenter.default.removeObserver(self, name: UIApplication.didEnterBackgroundNotification, object: nil) NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil) #endif } @@ -314,10 +322,7 @@ public final class WalletConnectClient { @objc private func appWillEnterForeground() { wakuRelay.connect() + registerBackgroundTask() } - - @objc - private func appDidEnterBackground() { - wakuRelay.disconnect(closeCode: .goingAway) - } + } From 12c06d4a3280c606ca87712f96afaea323598ebc Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 21 Jan 2022 09:34:02 +0100 Subject: [PATCH 05/19] add os requirement --- Sources/WalletConnect/WalletConnectClient.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/WalletConnect/WalletConnectClient.swift b/Sources/WalletConnect/WalletConnectClient.swift index dbb714472..5f5cd0157 100644 --- a/Sources/WalletConnect/WalletConnectClient.swift +++ b/Sources/WalletConnect/WalletConnectClient.swift @@ -31,8 +31,10 @@ public final class WalletConnectClient { private let secureStorage: SecureStorage private let pairingQueue = DispatchQueue(label: "com.walletconnect.sdk.client.pairing", qos: .userInitiated) private let history: JsonRpcHistory +#if os(iOS) private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid - +#endif + // MARK: - Initializers /// Initializes and returns newly created WalletConnect Client Instance. Establishes a network connection with the relay @@ -73,16 +75,20 @@ public final class WalletConnectClient { } func registerBackgroundTask() { +#if os(iOS) self.backgroundTaskID = UIApplication.shared.beginBackgroundTask (withName: "Finish Network Tasks") { [weak self] in self?.endBackgroundTask() } +#endif } func endBackgroundTask() { +#if os(iOS) wakuRelay.disconnect(closeCode: .goingAway) print("Background task ended.") UIApplication.shared.endBackgroundTask(backgroundTaskID) backgroundTaskID = .invalid +#endif } deinit { unsubscribeNotificationCenter() From 6794a6fa630905a651177ad4ccd3a1027121a983 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 21 Jan 2022 09:38:06 +0100 Subject: [PATCH 06/19] silent warnings --- Sources/Relayer/WakuNetworkRelay.swift | 2 +- Sources/WalletConnect/Engine/SessionEngine.swift | 2 +- Sources/WalletConnect/Relay/WalletConnectRelay.swift | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Relayer/WakuNetworkRelay.swift b/Sources/Relayer/WakuNetworkRelay.swift index 8e1eb99fc..e126b30b9 100644 --- a/Sources/Relayer/WakuNetworkRelay.swift +++ b/Sources/Relayer/WakuNetworkRelay.swift @@ -184,7 +184,7 @@ public final class WakuNetworkRelay { private func acknowledgeSubscription(requestId: Int64) { let response = JSONRPCResponse(id: requestId, result: AnyCodable(true)) let responseJson = try! response.json() - try? jsonRpcSubscriptionsHistory.resolve(response: JsonRpcResponseTypes.response(response)) + _ = try? jsonRpcSubscriptionsHistory.resolve(response: JsonRpcResponseTypes.response(response)) dispatcher.send(responseJson) { [weak self] error in if let error = error { self?.logger.debug("Failed to Respond for request id: \(requestId), error: \(error)") diff --git a/Sources/WalletConnect/Engine/SessionEngine.swift b/Sources/WalletConnect/Engine/SessionEngine.swift index 534de8e24..cea274cd0 100644 --- a/Sources/WalletConnect/Engine/SessionEngine.swift +++ b/Sources/WalletConnect/Engine/SessionEngine.swift @@ -366,7 +366,7 @@ final class SessionEngine { if let error = error { logger.error(error) } else { - try? sequencesStore.setSequence(session) + sequencesStore.setSequence(session) onSessionUpgrade?(session.topic, newPermissions) } } diff --git a/Sources/WalletConnect/Relay/WalletConnectRelay.swift b/Sources/WalletConnect/Relay/WalletConnectRelay.swift index 6e3c2c926..c0f39e4e0 100644 --- a/Sources/WalletConnect/Relay/WalletConnectRelay.swift +++ b/Sources/WalletConnect/Relay/WalletConnectRelay.swift @@ -103,10 +103,10 @@ class WalletConnectRelay: WalletConnectRelaying { func respond(topic: String, response: JsonRpcResponseTypes, completion: @escaping ((Error?)->())) { do { - try jsonRpcHistory.resolve(response: response) + _ = try jsonRpcHistory.resolve(response: response) let message = try jsonRpcSerialiser.serialise(topic: topic, encodable: response.value) logger.debug("Responding....topic: \(topic)") - networkRelayer.publish(topic: topic, payload: message) { [weak self] error in + networkRelayer.publish(topic: topic, payload: message) { error in completion(error) } } catch WalletConnectError.internal(.jsonRpcDuplicateDetected) { From 6bd01ab7e2408a151e97dd932561ac9eb8f8f868 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 21 Jan 2022 12:21:33 +0100 Subject: [PATCH 07/19] savepoint --- Example/DApp/ActivePairingItem.swift | 12 +- Example/DApp/ClientDelegate.swift | 65 ++++++++ Example/DApp/ProposerView.swift | 2 +- Example/DApp/ProposerViewController.swift | 144 +++--------------- Example/DApp/SceneDelegate.swift | 54 +++---- Example/DApp/SelectChainViewController.swift | 92 +++++++++++ Example/ExampleApp.xcodeproj/project.pbxproj | 8 + .../WalletConnect/Engine/SessionEngine.swift | 6 +- Sources/WalletConnect/Session.swift | 1 + .../WalletConnect/WalletConnectClient.swift | 6 +- 10 files changed, 222 insertions(+), 168 deletions(-) create mode 100644 Example/DApp/ClientDelegate.swift create mode 100644 Example/DApp/SelectChainViewController.swift diff --git a/Example/DApp/ActivePairingItem.swift b/Example/DApp/ActivePairingItem.swift index 96899b9d7..470a15fdf 100644 --- a/Example/DApp/ActivePairingItem.swift +++ b/Example/DApp/ActivePairingItem.swift @@ -1,6 +1,6 @@ -struct ActivePairingItem { - let peerName: String - let peerURL: String - let iconURL: String - let topic: String -} +//struct ActivePairingItem { +// let peerName: String +// let peerURL: String +// let iconURL: String +// let topic: String +//} diff --git a/Example/DApp/ClientDelegate.swift b/Example/DApp/ClientDelegate.swift new file mode 100644 index 000000000..0bfe1cf43 --- /dev/null +++ b/Example/DApp/ClientDelegate.swift @@ -0,0 +1,65 @@ + +import WalletConnect +import Foundation + + +class ClientDelegate: WalletConnectClientDelegate { + var client: WalletConnectClient + var onSessionSettled: ((Session)->())? + var onPairingSettled: ((Pairing)->())? + var onSessionProposal: ((Session.Proposal)->())? + var onSessionRequest: ((Request)->())? + var onSessionRejected: ((String, Reason)->())? + var onSessionDelete: (()->())? + var onSessionUpgrade: ((String, Session.Permissions)->())? + var onSessionUpdate: ((String, Set)->())? + var onNotificationReceived: ((Session.Notification, String)->())? + var onPairingUpdate: ((String, AppMetadata)->())? + + static var shared: ClientDelegate = ClientDelegate() + private init() { + let metadata = AppMetadata( + name: "Dapp Example", + description: "a description", + url: "wallet.connect", + icons: ["https://gblobscdn.gitbook.com/spaces%2F-LJJeCjcLrr53DcT1Ml7%2Favatar.png?alt=media"]) + self.client = WalletConnectClient( + metadata: metadata, + projectId: "52af113ee0c1e1a20f4995730196c13e", + isController: false, + relayHost: "relay.dev.walletconnect.com" + ) + client.delegate = self + } + + func didReject(pendingSessionTopic: String, reason: Reason) { + onSessionRejected?(pendingSessionTopic, reason) + } + func didSettle(session: Session) { + onSessionSettled?(session) + } + func didSettle(pairing: Pairing) { + onPairingSettled?(pairing) + } + func didReceive(sessionProposal: Session.Proposal) { + onSessionProposal?(sessionProposal) + } + func didReceive(sessionRequest: Request) { + onSessionRequest?(sessionRequest) + } + func didDelete(sessionTopic: String, reason: Reason) { + onSessionDelete?() + } + func didUpgrade(sessionTopic: String, permissions: Session.Permissions) { + onSessionUpgrade?(sessionTopic, permissions) + } + func didUpdate(sessionTopic: String, accounts: Set) { + onSessionUpdate?(sessionTopic, accounts) + } + func didReceive(notification: Session.Notification, sessionTopic: String) { + onNotificationReceived?(notification, sessionTopic) + } + func didUpdate(pairingTopic: String, appMetadata: AppMetadata) { + onPairingUpdate?(pairingTopic, appMetadata) + } +} diff --git a/Example/DApp/ProposerView.swift b/Example/DApp/ProposerView.swift index 626d7e41b..e7d210251 100644 --- a/Example/DApp/ProposerView.swift +++ b/Example/DApp/ProposerView.swift @@ -4,7 +4,7 @@ final class ProposerView: UIView { let tableView: UITableView = { let tableView = UITableView(frame: .zero, style: .insetGrouped) tableView.backgroundColor = .tertiarySystemBackground - tableView.register(ActivePairingCell.self, forCellReuseIdentifier: "sessionCell") + tableView.register(ActivePairingCell.self, forCellReuseIdentifier: "pairincCell") return tableView }() diff --git a/Example/DApp/ProposerViewController.swift b/Example/DApp/ProposerViewController.swift index afd7ec943..143988634 100644 --- a/Example/DApp/ProposerViewController.swift +++ b/Example/DApp/ProposerViewController.swift @@ -1,79 +1,53 @@ import UIKit import WalletConnect - +struct AccountDetails { + let chain: String + let methods: [String] + let account: String +} final class ProposerViewController: UIViewController { - let client: WalletConnectClient = { - let metadata = AppMetadata( - name: "Example Proposer", - description: "a description", - url: "wallet.connect", - icons: ["https://gblobscdn.gitbook.com/spaces%2F-LJJeCjcLrr53DcT1Ml7%2Favatar.png?alt=media"]) - return WalletConnectClient( - metadata: metadata, - projectId: "52af113ee0c1e1a20f4995730196c13e", - isController: false, - relayHost: "relay.dev.walletconnect.com", - clientName: "proposer" - ) - }() - - var activeItems: [ActivePairingItem] = [] - private var currentURI: String? + let client = ClientDelegate.shared.client + let session: Session + var activeItems: [AccountDetails] = [] private let proposerView: ProposerView = { ProposerView() }() + init(session: Session) { + self.session = session + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + override func loadView() { view = proposerView } override func viewDidLoad() { super.viewDidLoad() - navigationItem.title = "Dapp" + navigationItem.title = "Accounts" navigationItem.rightBarButtonItem = UIBarButtonItem( - title: "Connect", + title: "Disconnect", style: .plain, target: self, - action: #selector(connect) + action: #selector(disconnect) ) proposerView.tableView.dataSource = self proposerView.tableView.delegate = self - - client.delegate = self client.logger.setLogging(level: .debug) - } - - @objc func copyURI() { - UIPasteboard.general.string = currentURI + session. } @objc - private func connect() { - print("[PROPOSER] Connecting to a pairing...") - let permissions = Session.Permissions( - blockchains: ["a chain"], - methods: ["a method"], - notifications: [] - ) - do { - if let uri = try client.connect(sessionPermissions: permissions) { - showConnectScreen(uriString: uri) - } - } catch { - print("[PROPOSER] Pairing connect error: \(error)") - } - } - - private func showConnectScreen(uriString: String) { - DispatchQueue.main.async { [unowned self] in - let vc = ConnectViewController(uri: uriString) - present(vc, animated: true, completion: nil) - } + private func disconnect() { + client.disconnect(topic: session.topic, reason: Reason(code: 0, message: "disconnect")) } - } extension ProposerViewController: UITableViewDataSource, UITableViewDelegate { @@ -83,81 +57,11 @@ extension ProposerViewController: UITableViewDataSource, UITableViewDelegate { } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "sessionCell", for: indexPath) as! ActivePairingCell + let cell = tableView.dequeueReusableCell(withIdentifier: "pairingCell", for: indexPath) as! ActivePairingCell cell.item = activeItems[indexPath.row] return cell } - func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { - if editingStyle == .delete { - let item = activeItems[indexPath.row] - client.disconnect(topic: item.topic, reason: Reason(code: 0, message: "disconnect")) - activeItems.remove(at: indexPath.row) - tableView.deleteRows(at: [indexPath], with: .automatic) - } - } - - func tableView(_ tableView: UITableView, titleForDeleteConfirmationButtonForRowAt indexPath: IndexPath) -> String? { - "Disconnect" - } - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - print("did select row \(indexPath)") - } -} - -extension ProposerViewController: WalletConnectClientDelegate { - - func didReceive(sessionProposal: Session.Proposal) { - print("[PROPOSER] WC: Did receive session proposal") - } - - func didReceive(sessionRequest: Request) { - print("[PROPOSER] WC: Did receive session request") - } - - func didReceive(notification: Session.Notification, sessionTopic: String) { - - } - - func didUpgrade(sessionTopic: String, permissions: Session.Permissions) { - - } - - func didUpdate(sessionTopic: String, accounts: Set) { - - } - - func didUpdate(pairingTopic: String, appMetadata: AppMetadata) { - - } - - func didDelete(sessionTopic: String, reason: Reason) { - - } - - func didSettle(session: Session) { - print("[PROPOSER] WC: Did settle session") - } - - func didSettle(pairing: Pairing) { - print("[PROPOSER] WC: Did settle pairing") - let settledPairings = client.getSettledPairings() - let activePairings = settledPairings.map { pairing -> ActivePairingItem in - let peer = pairing.peer - return ActivePairingItem( - peerName: peer?.name ?? "", - peerURL: peer?.url ?? "", - iconURL: peer?.icons?.first ?? "", - topic: pairing.topic) - } - DispatchQueue.main.async { - self.activeItems = activePairings - self.proposerView.tableView.reloadData() - } - } - - func didReject(pendingSessionTopic: String, reason: Reason) { - print("[PROPOSER] WC: Did reject session") } } diff --git a/Example/DApp/SceneDelegate.swift b/Example/DApp/SceneDelegate.swift index bf65db1b6..527e1e6e6 100644 --- a/Example/DApp/SceneDelegate.swift +++ b/Example/DApp/SceneDelegate.swift @@ -1,9 +1,3 @@ -// -// SceneDelegate.swift -// DApp -// -// Created by Admin on 19/01/2022. -// import UIKit @@ -18,38 +12,28 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). guard let windowScene = (scene as? UIWindowScene) else { return } window = UIWindow(windowScene: windowScene) - window?.rootViewController = UINavigationController(rootViewController: ProposerViewController()) - window?.makeKeyAndVisible() - } - - func sceneDidDisconnect(_ scene: UIScene) { - // Called as the scene is being released by the system. - // This occurs shortly after the scene enters the background, or when its session is discarded. - // Release any resources associated with this scene that can be re-created the next time the scene connects. - // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). - } - - func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. - } - - func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). + if ClientDelegate.shared.client.getSettledSessions().count == 0 { + showSelectChainScreen() + } else { + + } } - func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. + func showSelectChainScreen() { + let vc = SelectChainViewController() + vc.onSessionSettled = { [unowned self] session in + DispatchQueue.main.async { + showAccountsScreen(session) + } + } + window?.rootViewController = vc + window?.makeKeyAndVisible() } - - func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. + + func showAccountsScreen(_ session: Session) { + window?.rootViewController = UINavigationController(rootViewController: ProposerViewController(session: session)) + window?.makeKeyAndVisible() } - - + } diff --git a/Example/DApp/SelectChainViewController.swift b/Example/DApp/SelectChainViewController.swift new file mode 100644 index 000000000..fae8f019f --- /dev/null +++ b/Example/DApp/SelectChainViewController.swift @@ -0,0 +1,92 @@ + + +import Foundation +import WalletConnect +import UIKit + +class SelectChainViewController: UIViewController { + private let selectChainView: SelectChainView = { + SelectChainView() + }() + let client = ClientDelegate.shared.client + var onSessionSettled: ((Session)->())? + override func viewDidLoad() { + super.viewDidLoad() + navigationItem.title = "Select Chain" + selectChainView.connectButton.addTarget(self, action: #selector(connect), for: .touchUpInside) + ClientDelegate.shared.onSessionSettled = { [unowned self] session in + onSessionSettled?(session) + } + } + + override func loadView() { + view = selectChainView + } + + @objc + private func connect() { + print("[PROPOSER] Connecting to a pairing...") + let permissions = Session.Permissions( + blockchains: ["a chain"], + methods: ["a method"], + notifications: [] + ) + do { + if let uri = try client.connect(sessionPermissions: permissions) { + showConnectScreen(uriString: uri) + } + } catch { + print("[PROPOSER] Pairing connect error: \(error)") + } + } + + private func showConnectScreen(uriString: String) { + DispatchQueue.main.async { [unowned self] in + let vc = ConnectViewController(uri: uriString) + present(vc, animated: true, completion: nil) + } + } +} + + +class SelectChainView: UIView { + let tableView: UITableView = { + let tableView = UITableView(frame: .zero, style: .insetGrouped) + tableView.backgroundColor = .tertiarySystemBackground + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "chain") + return tableView + }() + let connectButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("Connect", for: .normal) + button.backgroundColor = .systemBlue + button.tintColor = .white + button.layer.cornerRadius = 8 + return button + }() + + override init(frame: CGRect) { + super.init(frame: frame) + backgroundColor = .systemBackground + addSubview(tableView) + addSubview(connectButton) + + subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } + + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 16), + tableView.leadingAnchor.constraint(equalTo: leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: trailingAnchor), + tableView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor), + + connectButton.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -16), + connectButton.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor), + connectButton.heightAnchor.constraint(equalToConstant: 44), + connectButton.widthAnchor.constraint(equalToConstant: 120), + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index e0530973b..e35c36aaa 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -38,6 +38,8 @@ 84CE64392798228D00142511 /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE64382798228D00142511 /* Web3 */; }; 84CE643B2798229100142511 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE643A2798229100142511 /* WalletConnect */; }; 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE643C2798322600142511 /* ConnectViewController.swift */; }; + 84CE6444279AB5AD00142511 /* SelectChainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */; }; + 84CE6446279ABBF300142511 /* ClientDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6445279ABBF300142511 /* ClientDelegate.swift */; }; 84F568C2279582D200D0A289 /* Signer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C1279582D200D0A289 /* Signer.swift */; }; 84F568C42795832A00D0A289 /* EthereumTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C32795832A00D0A289 /* EthereumTransaction.swift */; }; /* End PBXBuildFile section */ @@ -88,6 +90,8 @@ 84CE64332798222400142511 /* ActivePairingCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ActivePairingCell.swift; path = DApp/ActivePairingCell.swift; sourceTree = SOURCE_ROOT; }; 84CE64362798224900142511 /* ActivePairingItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivePairingItem.swift; sourceTree = ""; }; 84CE643C2798322600142511 /* ConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = ""; }; + 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectChainViewController.swift; sourceTree = ""; }; + 84CE6445279ABBF300142511 /* ClientDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientDelegate.swift; sourceTree = ""; }; 84F568C1279582D200D0A289 /* Signer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signer.swift; sourceTree = ""; }; 84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -227,6 +231,8 @@ 84CE642027981DED00142511 /* SceneDelegate.swift */, 84CE642227981DED00142511 /* ViewController.swift */, 761C649926FB7ABB004239D1 /* ProposerViewController.swift */, + 84CE6445279ABBF300142511 /* ClientDelegate.swift */, + 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */, 84CE643C2798322600142511 /* ConnectViewController.swift */, 7603D74C2703429A00DD27A2 /* ProposerView.swift */, 84CE642727981DF000142511 /* Assets.xcassets */, @@ -408,6 +414,7 @@ buildActionMask = 2147483647; files = ( 84CE6430279820F600142511 /* ProposerViewController.swift in Sources */, + 84CE6446279ABBF300142511 /* ClientDelegate.swift in Sources */, 84CE642327981DED00142511 /* ViewController.swift in Sources */, 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */, 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */, @@ -415,6 +422,7 @@ 84CE6431279820F600142511 /* ProposerView.swift in Sources */, 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */, 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */, + 84CE6444279AB5AD00142511 /* SelectChainViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/WalletConnect/Engine/SessionEngine.swift b/Sources/WalletConnect/Engine/SessionEngine.swift index cea274cd0..dd55db8c0 100644 --- a/Sources/WalletConnect/Engine/SessionEngine.swift +++ b/Sources/WalletConnect/Engine/SessionEngine.swift @@ -56,7 +56,7 @@ final class SessionEngine { sequencesStore.getAll().compactMap { guard let settled = $0.settled else { return nil } let permissions = Session.Permissions(blockchains: settled.permissions.blockchain.chains, methods: settled.permissions.jsonrpc.methods) - return Session(topic: $0.topic, peer: settled.peer.metadata!, permissions: permissions) + return Session(topic: $0.topic, peer: settled.peer.metadata!, permissions: permissions, accounts: settled.state.accounts) } } @@ -476,7 +476,7 @@ final class SessionEngine { peer: approveParams.responder.metadata, permissions: Session.Permissions( blockchains: pendingSession.proposal.permissions.blockchain.chains, - methods: pendingSession.proposal.permissions.jsonrpc.methods)) + methods: pendingSession.proposal.permissions.jsonrpc.methods), accounts: settledSession.settled!.state.accounts) let response = JSONRPCResponse(id: requestId, result: AnyCodable(true)) relayer.respond(topic: topic, response: JsonRpcResponseTypes.response(response)) { [unowned self] error in @@ -544,7 +544,7 @@ final class SessionEngine { peer: proposal.proposer.metadata, permissions: Session.Permissions( blockchains: proposal.permissions.blockchain.chains, - methods: proposal.permissions.jsonrpc.methods)) + methods: proposal.permissions.jsonrpc.methods), accounts: pendingSession.settled!.state.accounts) onApprovalAcknowledgement?(sessionSuccess) case .failure: wcSubscriber.removeSubscription(topic: topic) diff --git a/Sources/WalletConnect/Session.swift b/Sources/WalletConnect/Session.swift index cd790bf29..6b371767b 100644 --- a/Sources/WalletConnect/Session.swift +++ b/Sources/WalletConnect/Session.swift @@ -7,6 +7,7 @@ public struct Session { public let topic: String public let peer: AppMetadata public let permissions: Permissions + public let accounts: Set } extension Session { diff --git a/Sources/WalletConnect/WalletConnectClient.swift b/Sources/WalletConnect/WalletConnectClient.swift index 6c9206158..b8ce9e566 100644 --- a/Sources/WalletConnect/WalletConnectClient.swift +++ b/Sources/WalletConnect/WalletConnectClient.swift @@ -268,9 +268,9 @@ public final class WalletConnectClient { self?.delegate?.didSettle(pairing: settledPairing) } sessionEngine.onSessionApproved = { [unowned self] settledSession in - let permissions = Session.Permissions.init(blockchains: settledSession.permissions.blockchains, methods: settledSession.permissions.methods) - let session = Session(topic: settledSession.topic, peer: settledSession.peer, permissions: permissions) - delegate?.didSettle(session: session) +// let permissions = Session.Permissions.init(blockchains: settledSession.permissions.blockchains, methods: settledSession.permissions.methods) +// let session = Session(topic: settledSession.topic, peer: settledSession.peer, permissions: permissions, accounts: settledSession.accounts) + delegate?.didSettle(session: settledSession) } sessionEngine.onApprovalAcknowledgement = { [weak self] session in self?.delegate?.didSettle(session: session) From 391378adf4f1e5a8522101f649e1ca376674235a Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 21 Jan 2022 12:32:55 +0100 Subject: [PATCH 08/19] add accounts to public session model --- Sources/WalletConnect/Engine/SessionEngine.swift | 3 ++- Sources/WalletConnect/WalletConnectClient.swift | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Sources/WalletConnect/Engine/SessionEngine.swift b/Sources/WalletConnect/Engine/SessionEngine.swift index dd55db8c0..4f608c89b 100644 --- a/Sources/WalletConnect/Engine/SessionEngine.swift +++ b/Sources/WalletConnect/Engine/SessionEngine.swift @@ -536,6 +536,7 @@ final class SessionEngine { } switch result { case .success: + guard let settledSession = try? sequencesStore.getSequence(forTopic: settledTopic) else {return} crypto.deleteAgreementSecret(for: topic) wcSubscriber.removeSubscription(topic: topic) sequencesStore.delete(topic: topic) @@ -544,7 +545,7 @@ final class SessionEngine { peer: proposal.proposer.metadata, permissions: Session.Permissions( blockchains: proposal.permissions.blockchain.chains, - methods: proposal.permissions.jsonrpc.methods), accounts: pendingSession.settled!.state.accounts) + methods: proposal.permissions.jsonrpc.methods), accounts: settledSession.settled!.state.accounts) onApprovalAcknowledgement?(sessionSuccess) case .failure: wcSubscriber.removeSubscription(topic: topic) diff --git a/Sources/WalletConnect/WalletConnectClient.swift b/Sources/WalletConnect/WalletConnectClient.swift index b8ce9e566..05e8188ac 100644 --- a/Sources/WalletConnect/WalletConnectClient.swift +++ b/Sources/WalletConnect/WalletConnectClient.swift @@ -268,8 +268,6 @@ public final class WalletConnectClient { self?.delegate?.didSettle(pairing: settledPairing) } sessionEngine.onSessionApproved = { [unowned self] settledSession in -// let permissions = Session.Permissions.init(blockchains: settledSession.permissions.blockchains, methods: settledSession.permissions.methods) -// let session = Session(topic: settledSession.topic, peer: settledSession.peer, permissions: permissions, accounts: settledSession.accounts) delegate?.didSettle(session: settledSession) } sessionEngine.onApprovalAcknowledgement = { [weak self] session in From 557e4d8f3d27a7c12c88a0308f3bbd28e1463ae4 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Fri, 21 Jan 2022 14:00:19 +0100 Subject: [PATCH 09/19] savepoint --- ...ler.swift => AccountsViewController.swift} | 33 ++++++-- Example/DApp/ActivePairingCell.swift | 78 ------------------ .../eip155:1.imageset/Contents.json | 21 +++++ .../eip155:1.imageset/ethereum.png | Bin 0 -> 21485 bytes Example/DApp/ProposerView.swift | 4 +- Example/DApp/SceneDelegate.swift | 13 ++- Example/ExampleApp.xcodeproj/project.pbxproj | 12 +-- 7 files changed, 60 insertions(+), 101 deletions(-) rename Example/DApp/{ProposerViewController.swift => AccountsViewController.swift} (63%) delete mode 100644 Example/DApp/ActivePairingCell.swift create mode 100644 Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json create mode 100644 Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum.png diff --git a/Example/DApp/ProposerViewController.swift b/Example/DApp/AccountsViewController.swift similarity index 63% rename from Example/DApp/ProposerViewController.swift rename to Example/DApp/AccountsViewController.swift index 143988634..003f38f40 100644 --- a/Example/DApp/ProposerViewController.swift +++ b/Example/DApp/AccountsViewController.swift @@ -5,11 +5,12 @@ struct AccountDetails { let methods: [String] let account: String } -final class ProposerViewController: UIViewController { +final class AccountsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { let client = ClientDelegate.shared.client let session: Session - var activeItems: [AccountDetails] = [] + var accountsDetails: [AccountDetails] = [] + var onDisconnect: (()->())? private let proposerView: ProposerView = { ProposerView() @@ -41,27 +42,41 @@ final class ProposerViewController: UIViewController { proposerView.tableView.dataSource = self proposerView.tableView.delegate = self client.logger.setLogging(level: .debug) - session. + session.permissions.blockchains.forEach { chain in + session.accounts.forEach { account in + accountsDetails.append(AccountDetails(chain: chain, methods: Array(session.permissions.methods), account: account)) + } + } } @objc private func disconnect() { client.disconnect(topic: session.topic, reason: Reason(code: 0, message: "disconnect")) + onDisconnect?() } -} - -extension ProposerViewController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - activeItems.count + accountsDetails.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "pairingCell", for: indexPath) as! ActivePairingCell - cell.item = activeItems[indexPath.row] + let cell = tableView.dequeueReusableCell(withIdentifier: "accountCell", for: indexPath) + let details = accountsDetails[indexPath.row] + cell.textLabel?.text = details.account + cell.imageView?.image = UIImage(named: details.chain) return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + showSessionScreen() + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 70 } + + func showSessionScreen() { + + } + } diff --git a/Example/DApp/ActivePairingCell.swift b/Example/DApp/ActivePairingCell.swift deleted file mode 100644 index ca68cff75..000000000 --- a/Example/DApp/ActivePairingCell.swift +++ /dev/null @@ -1,78 +0,0 @@ -import UIKit - -final class ActivePairingCell: UITableViewCell { - - var item: ActivePairingItem? { - didSet { - if let item = item { - show(item) - } - } - } - - private let iconView: UIImageView = { - let imageView = UIImageView() - imageView.contentMode = .scaleAspectFit - imageView.layer.cornerRadius = 20 - return imageView - }() - - private let titleLabel: UILabel = { - let label = UILabel() - label.setContentHuggingPriority(.defaultHigh, for: .vertical) - return label - }() - - private let subtitleLabel: UILabel = { - let label = UILabel() - label.font = UIFont.preferredFont(forTextStyle: .caption1) - label.textColor = .secondaryLabel - return label - }() - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) - accessoryType = .disclosureIndicator - selectionStyle = .none - - contentView.addSubview(iconView) - contentView.addSubview(titleLabel) - contentView.addSubview(subtitleLabel) - - contentView.subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } - - NSLayoutConstraint.activate([ - iconView.heightAnchor.constraint(equalToConstant: 40), - iconView.heightAnchor.constraint(equalTo: iconView.widthAnchor), - iconView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), - iconView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20), - - titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 10), - titleLabel.leadingAnchor.constraint(equalTo: iconView.trailingAnchor, constant: 16), - titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16), - - subtitleLabel.topAnchor.constraint(equalTo: titleLabel.lastBaselineAnchor, constant: 6), - subtitleLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor), - subtitleLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor), - subtitleLabel.lastBaselineAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -12) - ]) - } - - private func show(_ item: ActivePairingItem) { - titleLabel.text = item.peerName - subtitleLabel.text = item.peerURL - iconView.image = nil - guard let iconURL = URL(string: item.iconURL) else { return } - DispatchQueue.global().async { - if let imageData = try? Data(contentsOf: iconURL) { - DispatchQueue.main.async { [weak self] in - self?.iconView.image = UIImage(data: imageData) - } - } - } - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json b/Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json new file mode 100644 index 000000000..a816052d5 --- /dev/null +++ b/Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "ethereum.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum.png b/Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum.png new file mode 100644 index 0000000000000000000000000000000000000000..11a19262790e8f1b9cfd5c8588d4b3eb4c430f0e GIT binary patch literal 21485 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

)v#`;E?2Dv!C{ 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 Date: Mon, 24 Jan 2022 10:23:49 +0100 Subject: [PATCH 10/19] Add Account Request View Controller --- .../AccountRequest/AccountRequestView.swift | 71 +++++++++++++++++++ .../AccountRequestViewController.swift | 56 +++++++++++++++ Example/DApp/AccountsViewController.swift | 7 +- Example/ExampleApp.xcodeproj/project.pbxproj | 16 +++++ 4 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 Example/DApp/AccountRequest/AccountRequestView.swift create mode 100644 Example/DApp/AccountRequest/AccountRequestViewController.swift diff --git a/Example/DApp/AccountRequest/AccountRequestView.swift b/Example/DApp/AccountRequest/AccountRequestView.swift new file mode 100644 index 000000000..d159c1675 --- /dev/null +++ b/Example/DApp/AccountRequest/AccountRequestView.swift @@ -0,0 +1,71 @@ + +import UIKit +import Foundation + +class AccountRequestView: UIView { + let iconView: UIImageView = { + let imageView = UIImageView() + imageView.contentMode = .scaleAspectFit + imageView.backgroundColor = .systemFill + imageView.layer.cornerRadius = 32 + return imageView + }() + + let nameLabel: UILabel = { + let label = UILabel() + label.font = UIFont.systemFont(ofSize: 17.0, weight: .heavy) + return label + }() + let descriptionLabel: UILabel = { + let label = UILabel() + label.font = UIFont.preferredFont(forTextStyle: .subheadline) + label.textColor = .secondaryLabel + label.numberOfLines = 0 + label.textAlignment = .center + return label + }() + + let headerStackView: UIStackView = { + let stackView = UIStackView() + stackView.axis = .vertical + stackView.spacing = 16 + stackView.alignment = .center + return stackView + }() + + let tableView = UITableView() + + override init(frame: CGRect) { + super.init(frame: frame) + backgroundColor = .systemBackground + + addSubview(iconView) + addSubview(headerStackView) + addSubview(tableView) + + headerStackView.addArrangedSubview(nameLabel) + headerStackView.addArrangedSubview(descriptionLabel) + + subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } + + NSLayoutConstraint.activate([ + iconView.topAnchor.constraint(equalTo: topAnchor, constant: 64), + iconView.centerXAnchor.constraint(equalTo: centerXAnchor), + iconView.widthAnchor.constraint(equalToConstant: 64), + iconView.heightAnchor.constraint(equalToConstant: 64), + + headerStackView.topAnchor.constraint(equalTo: iconView.bottomAnchor, constant: 32), + headerStackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 32), + headerStackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -32), + + tableView.topAnchor.constraint(equalTo: headerStackView.bottomAnchor, constant: 0), + tableView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0), + tableView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0), + tableView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor), + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Example/DApp/AccountRequest/AccountRequestViewController.swift b/Example/DApp/AccountRequest/AccountRequestViewController.swift new file mode 100644 index 000000000..5aa9cdc38 --- /dev/null +++ b/Example/DApp/AccountRequest/AccountRequestViewController.swift @@ -0,0 +1,56 @@ + + +import Foundation +import UIKit +import WalletConnect + +class AccountRequestViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { + private let session: Session + private let client: WalletConnectClient = ClientDelegate.shared.client + private let chainId: String + private let account: String + private let methods = ["eth_sendTransaction", "personal_sign", "eth_signTypedData"] + private let accountRequestView = { + AccountRequestView() + }() + + init(_ session: Session, chainId: String, account: String) { + self.session = session + self.chainId = chainId + self.account = account + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + view = accountRequestView + } + + override func viewDidLoad() { + super.viewDidLoad() + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + methods.count + } + + func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + return "Methods" + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) + cell.textLabel?.text = methods[indexPath.row] + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let method = methods[indexPath.row] + let requestParams = AnyCodable("") + let request = Request(topic: session.topic, method: method, params: params, chainId: chainId) + client.request(params: request) { _ in } + } +} diff --git a/Example/DApp/AccountsViewController.swift b/Example/DApp/AccountsViewController.swift index 003f38f40..5f4e6208e 100644 --- a/Example/DApp/AccountsViewController.swift +++ b/Example/DApp/AccountsViewController.swift @@ -68,15 +68,16 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - showSessionScreen() + showAccountRequestScreen() } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 70 } - func showSessionScreen() { - + func showAccountRequestScreen() { + let vc = AccountRequestViewController() + navigationController?.pushViewController(vc, animated: true) } } diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 9d2deb4f3..3c26aea10 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -39,6 +39,8 @@ 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE643C2798322600142511 /* ConnectViewController.swift */; }; 84CE6444279AB5AD00142511 /* SelectChainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */; }; 84CE6446279ABBF300142511 /* ClientDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6445279ABBF300142511 /* ClientDelegate.swift */; }; + 84CE6448279AE68600142511 /* AccountRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6447279AE68600142511 /* AccountRequestViewController.swift */; }; + 84CE644B279EA1FA00142511 /* AccountRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE644A279EA1FA00142511 /* AccountRequestView.swift */; }; 84F568C2279582D200D0A289 /* Signer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C1279582D200D0A289 /* Signer.swift */; }; 84F568C42795832A00D0A289 /* EthereumTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C32795832A00D0A289 /* EthereumTransaction.swift */; }; /* End PBXBuildFile section */ @@ -90,6 +92,8 @@ 84CE643C2798322600142511 /* ConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = ""; }; 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectChainViewController.swift; sourceTree = ""; }; 84CE6445279ABBF300142511 /* ClientDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientDelegate.swift; sourceTree = ""; }; + 84CE6447279AE68600142511 /* AccountRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRequestViewController.swift; sourceTree = ""; }; + 84CE644A279EA1FA00142511 /* AccountRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRequestView.swift; sourceTree = ""; }; 84F568C1279582D200D0A289 /* Signer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signer.swift; sourceTree = ""; }; 84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -228,6 +232,7 @@ 84CE642027981DED00142511 /* SceneDelegate.swift */, 84CE642227981DED00142511 /* ViewController.swift */, 761C649926FB7ABB004239D1 /* AccountsViewController.swift */, + 84CE6449279EA1E600142511 /* AccountRequest */, 84CE6445279ABBF300142511 /* ClientDelegate.swift */, 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */, 84CE643C2798322600142511 /* ConnectViewController.swift */, @@ -239,6 +244,15 @@ path = DApp; sourceTree = ""; }; + 84CE6449279EA1E600142511 /* AccountRequest */ = { + isa = PBXGroup; + children = ( + 84CE6447279AE68600142511 /* AccountRequestViewController.swift */, + 84CE644A279EA1FA00142511 /* AccountRequestView.swift */, + ); + path = AccountRequest; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -414,7 +428,9 @@ 84CE6446279ABBF300142511 /* ClientDelegate.swift in Sources */, 84CE642327981DED00142511 /* ViewController.swift in Sources */, 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */, + 84CE6448279AE68600142511 /* AccountRequestViewController.swift in Sources */, 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */, + 84CE644B279EA1FA00142511 /* AccountRequestView.swift in Sources */, 84CE6431279820F600142511 /* ProposerView.swift in Sources */, 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */, 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */, From 3e1cf4fcc8147a282143b137d1a445eb76dc8362 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 10:43:54 +0100 Subject: [PATCH 11/19] dapp savepoint --- .../DApp/AccountRequest/AccountRequestView.swift | 2 +- .../AccountRequestViewController.swift | 13 ++++++++----- Example/DApp/AccountsViewController.swift | 6 +++--- Example/DApp/SelectChainViewController.swift | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Example/DApp/AccountRequest/AccountRequestView.swift b/Example/DApp/AccountRequest/AccountRequestView.swift index d159c1675..a9f1229a6 100644 --- a/Example/DApp/AccountRequest/AccountRequestView.swift +++ b/Example/DApp/AccountRequest/AccountRequestView.swift @@ -38,7 +38,7 @@ class AccountRequestView: UIView { override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .systemBackground - + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "method_cell") addSubview(iconView) addSubview(headerStackView) addSubview(tableView) diff --git a/Example/DApp/AccountRequest/AccountRequestViewController.swift b/Example/DApp/AccountRequest/AccountRequestViewController.swift index 5aa9cdc38..55f32943f 100644 --- a/Example/DApp/AccountRequest/AccountRequestViewController.swift +++ b/Example/DApp/AccountRequest/AccountRequestViewController.swift @@ -3,6 +3,7 @@ import Foundation import UIKit import WalletConnect +import WalletConnectUtils class AccountRequestViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { private let session: Session @@ -14,10 +15,10 @@ class AccountRequestViewController: UIViewController, UITableViewDelegate, UITab AccountRequestView() }() - init(_ session: Session, chainId: String, account: String) { + init(session: Session, accountDetails: AccountDetails) { self.session = session - self.chainId = chainId - self.account = account + self.chainId = accountDetails.chain + self.account = accountDetails.account super.init(nibName: nil, bundle: nil) } @@ -31,6 +32,8 @@ class AccountRequestViewController: UIViewController, UITableViewDelegate, UITab override func viewDidLoad() { super.viewDidLoad() + accountRequestView.tableView.delegate = self + accountRequestView.tableView.dataSource = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -42,7 +45,7 @@ class AccountRequestViewController: UIViewController, UITableViewDelegate, UITab } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) + let cell = tableView.dequeueReusableCell(withIdentifier: "method_cell", for: indexPath) cell.textLabel?.text = methods[indexPath.row] return cell } @@ -50,7 +53,7 @@ class AccountRequestViewController: UIViewController, UITableViewDelegate, UITab func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let method = methods[indexPath.row] let requestParams = AnyCodable("") - let request = Request(topic: session.topic, method: method, params: params, chainId: chainId) + let request = Request(topic: session.topic, method: method, params: requestParams, chainId: chainId) client.request(params: request) { _ in } } } diff --git a/Example/DApp/AccountsViewController.swift b/Example/DApp/AccountsViewController.swift index 5f4e6208e..6d40059d1 100644 --- a/Example/DApp/AccountsViewController.swift +++ b/Example/DApp/AccountsViewController.swift @@ -68,15 +68,15 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - showAccountRequestScreen() + showAccountRequestScreen(accountsDetails[indexPath.row]) } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 70 } - func showAccountRequestScreen() { - let vc = AccountRequestViewController() + func showAccountRequestScreen(_ details: AccountDetails) { + let vc = AccountRequestViewController(session: session, accountDetails: details) navigationController?.pushViewController(vc, animated: true) } diff --git a/Example/DApp/SelectChainViewController.swift b/Example/DApp/SelectChainViewController.swift index fae8f019f..39bfac7a1 100644 --- a/Example/DApp/SelectChainViewController.swift +++ b/Example/DApp/SelectChainViewController.swift @@ -27,8 +27,8 @@ class SelectChainViewController: UIViewController { private func connect() { print("[PROPOSER] Connecting to a pairing...") let permissions = Session.Permissions( - blockchains: ["a chain"], - methods: ["a method"], + blockchains: ["eip155:1, eip155:137"], + methods: ["eth_sendTransaction", "personal_sign", "eth_signTypedData"], notifications: [] ) do { From cefe4b2a20a1f97d003695b5faf246f18f988d5f Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 11:45:28 +0100 Subject: [PATCH 12/19] fix account display --- Example/DApp/AccountsViewController.swift | 9 +++++---- Example/DApp/SelectChainViewController.swift | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Example/DApp/AccountsViewController.swift b/Example/DApp/AccountsViewController.swift index 6d40059d1..bf2357729 100644 --- a/Example/DApp/AccountsViewController.swift +++ b/Example/DApp/AccountsViewController.swift @@ -42,10 +42,11 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT proposerView.tableView.dataSource = self proposerView.tableView.delegate = self client.logger.setLogging(level: .debug) - session.permissions.blockchains.forEach { chain in - session.accounts.forEach { account in - accountsDetails.append(AccountDetails(chain: chain, methods: Array(session.permissions.methods), account: account)) - } + session.accounts.forEach { account in + let splits = account.split(separator: ":", omittingEmptySubsequences: false) + guard splits.count == 3 else { return } + let chain = String(splits[0] + ":" + splits[1]) + accountsDetails.append(AccountDetails(chain: chain, methods: Array(session.permissions.methods), account: account)) } } diff --git a/Example/DApp/SelectChainViewController.swift b/Example/DApp/SelectChainViewController.swift index 39bfac7a1..fcf7a634d 100644 --- a/Example/DApp/SelectChainViewController.swift +++ b/Example/DApp/SelectChainViewController.swift @@ -27,7 +27,7 @@ class SelectChainViewController: UIViewController { private func connect() { print("[PROPOSER] Connecting to a pairing...") let permissions = Session.Permissions( - blockchains: ["eip155:1, eip155:137"], + blockchains: ["eip155:1", "eip155:137"], methods: ["eth_sendTransaction", "personal_sign", "eth_signTypedData"], notifications: [] ) From 6124a6c9ff5f9224f456b3d8031b857410b3bf20 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 12:05:40 +0100 Subject: [PATCH 13/19] update dapp - request --- .../AccountRequest/AccountRequestView.swift | 10 ++++----- .../AccountRequestViewController.swift | 7 ++++++ Example/DApp/AccountsViewController.swift | 1 + .../eip155:1.imageset/Contents.json | 2 +- .../eip155:1.imageset/ethereum (1).png | Bin 0 -> 607 bytes .../eip155:1.imageset/ethereum.png | Bin 21485 -> 0 bytes .../eip155:137.imageset/Contents.json | 21 ++++++++++++++++++ .../eip155:137.imageset/coin.png | Bin 0 -> 837 bytes 8 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum (1).png delete mode 100644 Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum.png create mode 100644 Example/DApp/Assets.xcassets/eip155:137.imageset/Contents.json create mode 100644 Example/DApp/Assets.xcassets/eip155:137.imageset/coin.png diff --git a/Example/DApp/AccountRequest/AccountRequestView.swift b/Example/DApp/AccountRequest/AccountRequestView.swift index a9f1229a6..3f446422f 100644 --- a/Example/DApp/AccountRequest/AccountRequestView.swift +++ b/Example/DApp/AccountRequest/AccountRequestView.swift @@ -11,12 +11,12 @@ class AccountRequestView: UIView { return imageView }() - let nameLabel: UILabel = { + let chainLabel: UILabel = { let label = UILabel() label.font = UIFont.systemFont(ofSize: 17.0, weight: .heavy) return label }() - let descriptionLabel: UILabel = { + let accountLabel: UILabel = { let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .subheadline) label.textColor = .secondaryLabel @@ -43,16 +43,14 @@ class AccountRequestView: UIView { addSubview(headerStackView) addSubview(tableView) - headerStackView.addArrangedSubview(nameLabel) - headerStackView.addArrangedSubview(descriptionLabel) + headerStackView.addArrangedSubview(chainLabel) + headerStackView.addArrangedSubview(accountLabel) subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } NSLayoutConstraint.activate([ iconView.topAnchor.constraint(equalTo: topAnchor, constant: 64), iconView.centerXAnchor.constraint(equalTo: centerXAnchor), - iconView.widthAnchor.constraint(equalToConstant: 64), - iconView.heightAnchor.constraint(equalToConstant: 64), headerStackView.topAnchor.constraint(equalTo: iconView.bottomAnchor, constant: 32), headerStackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 32), diff --git a/Example/DApp/AccountRequest/AccountRequestViewController.swift b/Example/DApp/AccountRequest/AccountRequestViewController.swift index 55f32943f..052509f42 100644 --- a/Example/DApp/AccountRequest/AccountRequestViewController.swift +++ b/Example/DApp/AccountRequest/AccountRequestViewController.swift @@ -34,6 +34,9 @@ class AccountRequestViewController: UIViewController, UITableViewDelegate, UITab super.viewDidLoad() accountRequestView.tableView.delegate = self accountRequestView.tableView.dataSource = self + accountRequestView.iconView.image = UIImage(named: chainId) + accountRequestView.chainLabel.text = chainId + accountRequestView.accountLabel.text = account } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { @@ -55,5 +58,9 @@ class AccountRequestViewController: UIViewController, UITableViewDelegate, UITab let requestParams = AnyCodable("") let request = Request(topic: session.topic, method: method, params: requestParams, chainId: chainId) client.request(params: request) { _ in } + let alert = UIAlertController(title: "Request Sent", message: nil, preferredStyle: .alert) + let action = UIAlertAction(title: "OK", style: .cancel) + alert.addAction(action) + present(alert, animated: true) } } diff --git a/Example/DApp/AccountsViewController.swift b/Example/DApp/AccountsViewController.swift index bf2357729..373dc55df 100644 --- a/Example/DApp/AccountsViewController.swift +++ b/Example/DApp/AccountsViewController.swift @@ -65,6 +65,7 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT let details = accountsDetails[indexPath.row] cell.textLabel?.text = details.account cell.imageView?.image = UIImage(named: details.chain) + cell.textLabel?.numberOfLines = 0 return cell } diff --git a/Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json b/Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json index a816052d5..4664aca0a 100644 --- a/Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json +++ b/Example/DApp/Assets.xcassets/eip155:1.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "ethereum.png", + "filename" : "ethereum (1).png", "idiom" : "universal", "scale" : "1x" }, diff --git a/Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum (1).png b/Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum (1).png new file mode 100644 index 0000000000000000000000000000000000000000..35e1cb09f197e397776e57d86c2a389b965495c5 GIT binary patch literal 607 zcmV-l0-*hgP)OSw zO39Cinw3UYv+z$SshN#NSy*V~XNo3Eg-KbBDI;TCi|5cYubJ0X^Et0VXa~Nr|FFHZkhVd1B#Ua9N zd_Z>rz$(1Oco6{h1$oDpnEL}D>_@`qU`qh3P^I51OQhd&05SJWq;o5hdm{e*c#~4P zl2Y2d9DgaL-jvd%l+qM-VH0{=l8pWMrmEh#c;Ckm?%@HB#dskI{vL9ul;jf;(`z`X zs^;7zld6_69Qx^Y3+;xg-y9CT4=;kBtzjFCFCXosk`wOWi)d;Vw~8H@#W)&m1Jv5Z zQ+y2ae>J;}c#r3rYNc8JdS#}RHsG=9lKF%#bgSCPo}BY^%MDtg*G{qxpKAoqVtbKq t$)W%msHNjzsbBG5MTF~2ocd;|&rcd{k{Qv6AoBnK002ovPDHLkV1j+34W9r2 literal 0 HcmV?d00001 diff --git a/Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum.png b/Example/DApp/Assets.xcassets/eip155:1.imageset/ethereum.png deleted file mode 100644 index 11a19262790e8f1b9cfd5c8588d4b3eb4c430f0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21485 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

)v#`;E?2Dv!C{ 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 P00000NkvXXu0mjfc&CJ% literal 0 HcmV?d00001 From 6641a59e2f71cf062ee2d1fbc20219b617cb8152 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 13:10:13 +0100 Subject: [PATCH 14/19] Add eth_sendTransaction, personal_sign, eth_signTypedData requests to dapp --- .../AccountRequestViewController.swift | 102 +++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/Example/DApp/AccountRequest/AccountRequestViewController.swift b/Example/DApp/AccountRequest/AccountRequestViewController.swift index 052509f42..f1d74c00f 100644 --- a/Example/DApp/AccountRequest/AccountRequestViewController.swift +++ b/Example/DApp/AccountRequest/AccountRequestViewController.swift @@ -55,12 +55,112 @@ class AccountRequestViewController: UIViewController, UITableViewDelegate, UITab func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let method = methods[indexPath.row] - let requestParams = AnyCodable("") + let requestParams = getRequest(for: method) + + let request = Request(topic: session.topic, method: method, params: requestParams, chainId: chainId) client.request(params: request) { _ in } + presentConfirmationAlert() + } + + private func presentConfirmationAlert() { let alert = UIAlertController(title: "Request Sent", message: nil, preferredStyle: .alert) let action = UIAlertAction(title: "OK", style: .cancel) alert.addAction(action) present(alert, animated: true) } + + private func getRequest(for method: String) -> AnyCodable { + let account = "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83" + if method == "eth_sendTransaction" { + let tx = Stub.tx + return AnyCodable(tx) + } else if method == "personal_sign" { + return AnyCodable(["0xdeadbeaf", account]) + } else if method == "eth_signTypedData" { + return AnyCodable([account, Stub.eth_signTypedData]) + } + fatalError("not implemented") + } +} + +struct Transaction: Codable { + let from, to, data, gas: String + let gasPrice, value, nonce: String +} + +fileprivate enum Stub { + static let tx = [Transaction(from: "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", + to: "0x9b2055d370f73ec7d8a03e965129118dc8f5bf83", + data: "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675", + gas: "0x76c0", + gasPrice: "0x9184e72a000", + value: "0x9184e72a", + nonce: "0x117")] + static let eth_signTypedData = """ +{ +"types": { + "EIP712Domain": [ + { + "name": "name", + "type": "string" + }, + { + "name": "version", + "type": "string" + }, + { + "name": "chainId", + "type": "uint256" + }, + { + "name": "verifyingContract", + "type": "address" + } + ], + "Person": [ + { + "name": "name", + "type": "string" + }, + { + "name": "wallet", + "type": "address" + } + ], + "Mail": [ + { + "name": "from", + "type": "Person" + }, + { + "name": "to", + "type": "Person" + }, + { + "name": "contents", + "type": "string" + } + ] +}, +"primaryType": "Mail", +"domain": { + "name": "Ether Mail", + "version": "1", + "chainId": 1, + "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" +}, +"message": { + "from": { + "name": "Cow", + "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" + }, + "to": { + "name": "Bob", + "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" + }, + "contents": "Hello, Bob!" +} +} +""" } From 36dc796e5758470b813b6579a016912132576a1e Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 13:27:58 +0100 Subject: [PATCH 15/19] List chains on select chain vc --- Example/DApp/SceneDelegate.swift | 2 +- Example/DApp/SelectChainViewController.swift | 24 ++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Example/DApp/SceneDelegate.swift b/Example/DApp/SceneDelegate.swift index 20438a876..9f3943771 100644 --- a/Example/DApp/SceneDelegate.swift +++ b/Example/DApp/SceneDelegate.swift @@ -27,7 +27,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { showAccountsScreen(session) } } - window?.rootViewController = vc + window?.rootViewController = UINavigationController(rootViewController: vc) window?.makeKeyAndVisible() } diff --git a/Example/DApp/SelectChainViewController.swift b/Example/DApp/SelectChainViewController.swift index fcf7a634d..5e69240b9 100644 --- a/Example/DApp/SelectChainViewController.swift +++ b/Example/DApp/SelectChainViewController.swift @@ -4,15 +4,21 @@ import Foundation import WalletConnect import UIKit -class SelectChainViewController: UIViewController { +struct Chain { + let name: String + let id: String +} +class SelectChainViewController: UIViewController, UITableViewDataSource { private let selectChainView: SelectChainView = { SelectChainView() }() + let chains = [Chain(name: "Ethereum", id: "eip155:1"), Chain(name: "Polygon", id: "eip155:137")] let client = ClientDelegate.shared.client var onSessionSettled: ((Session)->())? override func viewDidLoad() { super.viewDidLoad() - navigationItem.title = "Select Chain" + navigationItem.title = "Available Chains" + selectChainView.tableView.dataSource = self selectChainView.connectButton.addTarget(self, action: #selector(connect), for: .touchUpInside) ClientDelegate.shared.onSessionSettled = { [unowned self] session in onSessionSettled?(session) @@ -46,6 +52,19 @@ class SelectChainViewController: UIViewController { present(vc, animated: true, completion: nil) } } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + chains.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "chain_cell", for: indexPath) + let chain = chains[indexPath.row] + cell.textLabel?.text = chain.name + cell.imageView?.image = UIImage(named: chain.id) + cell.selectionStyle = .none + return cell + } } @@ -67,6 +86,7 @@ class SelectChainView: UIView { override init(frame: CGRect) { super.init(frame: frame) + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "chain_cell") backgroundColor = .systemBackground addSubview(tableView) addSubview(connectButton) From ea332ceda633c115c15c7fb5bbe6ceec128f56eb Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 13:37:19 +0100 Subject: [PATCH 16/19] Update projct structure --- .../AccountsView.swift} | 2 +- .../AccountsViewController.swift | 12 +-- Example/DApp/ActivePairingItem.swift | 6 -- Example/DApp/ClientDelegate.swift | 2 +- .../ConnectView.swift} | 51 ------------ .../DApp/Connect/ConnectViewController.swift | 54 +++++++++++++ Example/DApp/Info.plist | 2 +- .../DApp/SelectChain/SelectChainView.swift | 48 ++++++++++++ .../SelectChainViewController.swift | 45 +---------- Example/DApp/ViewController.swift | 19 ----- Example/ExampleApp.xcodeproj/project.pbxproj | 54 +++++++++---- .../xcshareddata/xcschemes/DApp.xcscheme | 78 +++++++++++++++++++ Example/ExampleApp/Info.plist | 2 +- 13 files changed, 231 insertions(+), 144 deletions(-) rename Example/DApp/{ProposerView.swift => Accounts/AccountsView.swift} (96%) rename Example/DApp/{ => Accounts}/AccountsViewController.swift (93%) delete mode 100644 Example/DApp/ActivePairingItem.swift rename Example/DApp/{ConnectViewController.swift => Connect/ConnectView.swift} (54%) create mode 100644 Example/DApp/Connect/ConnectViewController.swift create mode 100644 Example/DApp/SelectChain/SelectChainView.swift rename Example/DApp/{ => SelectChain}/SelectChainViewController.swift (55%) delete mode 100644 Example/DApp/ViewController.swift create mode 100644 Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/DApp.xcscheme diff --git a/Example/DApp/ProposerView.swift b/Example/DApp/ Accounts/AccountsView.swift similarity index 96% rename from Example/DApp/ProposerView.swift rename to Example/DApp/ Accounts/AccountsView.swift index 49a42087e..afd428a0b 100644 --- a/Example/DApp/ProposerView.swift +++ b/Example/DApp/ Accounts/AccountsView.swift @@ -1,6 +1,6 @@ import UIKit -final class ProposerView: UIView { +final class AccountsView: UIView { let tableView: UITableView = { let tableView = UITableView(frame: .zero, style: .plain) tableView.backgroundColor = .tertiarySystemBackground diff --git a/Example/DApp/AccountsViewController.swift b/Example/DApp/ Accounts/AccountsViewController.swift similarity index 93% rename from Example/DApp/AccountsViewController.swift rename to Example/DApp/ Accounts/AccountsViewController.swift index 373dc55df..bb20aa733 100644 --- a/Example/DApp/AccountsViewController.swift +++ b/Example/DApp/ Accounts/AccountsViewController.swift @@ -1,10 +1,12 @@ import UIKit import WalletConnect + struct AccountDetails { let chain: String let methods: [String] let account: String } + final class AccountsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { let client = ClientDelegate.shared.client @@ -12,8 +14,8 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT var accountsDetails: [AccountDetails] = [] var onDisconnect: (()->())? - private let proposerView: ProposerView = { - ProposerView() + private let accountsView: AccountsView = { + AccountsView() }() init(session: Session) { @@ -26,7 +28,7 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT } override func loadView() { - view = proposerView + view = accountsView } override func viewDidLoad() { @@ -39,8 +41,8 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT target: self, action: #selector(disconnect) ) - proposerView.tableView.dataSource = self - proposerView.tableView.delegate = self + accountsView.tableView.dataSource = self + accountsView.tableView.delegate = self client.logger.setLogging(level: .debug) session.accounts.forEach { account in let splits = account.split(separator: ":", omittingEmptySubsequences: false) diff --git a/Example/DApp/ActivePairingItem.swift b/Example/DApp/ActivePairingItem.swift deleted file mode 100644 index 470a15fdf..000000000 --- a/Example/DApp/ActivePairingItem.swift +++ /dev/null @@ -1,6 +0,0 @@ -//struct ActivePairingItem { -// let peerName: String -// let peerURL: String -// let iconURL: String -// let topic: String -//} diff --git a/Example/DApp/ClientDelegate.swift b/Example/DApp/ClientDelegate.swift index 0bfe1cf43..12fa01da4 100644 --- a/Example/DApp/ClientDelegate.swift +++ b/Example/DApp/ClientDelegate.swift @@ -19,7 +19,7 @@ class ClientDelegate: WalletConnectClientDelegate { static var shared: ClientDelegate = ClientDelegate() private init() { let metadata = AppMetadata( - name: "Dapp Example", + name: "Swift Dapp", description: "a description", url: "wallet.connect", icons: ["https://gblobscdn.gitbook.com/spaces%2F-LJJeCjcLrr53DcT1Ml7%2Favatar.png?alt=media"]) diff --git a/Example/DApp/ConnectViewController.swift b/Example/DApp/Connect/ConnectView.swift similarity index 54% rename from Example/DApp/ConnectViewController.swift rename to Example/DApp/Connect/ConnectView.swift index ed77a9abb..ca7d7ad27 100644 --- a/Example/DApp/ConnectViewController.swift +++ b/Example/DApp/Connect/ConnectView.swift @@ -2,57 +2,6 @@ import Foundation import UIKit -class ConnectViewController: UIViewController { - let uriString: String - init(uri: String) { - self.uriString = uri - super.init(nibName: nil, bundle: nil) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - private let connectView: ConnectView = { - ConnectView() - }() - - override func loadView() { - view = connectView - } - - override func viewDidLoad() { - super.viewDidLoad() - DispatchQueue.global().async { [unowned self] in - if let qrImage = generateQRCode(from: uriString) { - DispatchQueue.main.async { - connectView.qrCodeView.image = qrImage - connectView.copyButton.isHidden = false - } - } - } - connectView.copyButton.addTarget(self, action: #selector(copyURI), for: .touchUpInside) - connectView.copyButton.isHidden = true - } - - - @objc func copyURI() { - UIPasteboard.general.string = uriString - } - - - private func generateQRCode(from string: String) -> UIImage? { - let data = string.data(using: .ascii) - if let filter = CIFilter(name: "CIQRCodeGenerator") { - filter.setValue(data, forKey: "inputMessage") - if let output = filter.outputImage { - return UIImage(ciImage: output) - } - } - return nil - } -} - final class ConnectView: UIView { let qrCodeView: UIImageView = { let imageView = UIImageView() diff --git a/Example/DApp/Connect/ConnectViewController.swift b/Example/DApp/Connect/ConnectViewController.swift new file mode 100644 index 000000000..ce75d2e18 --- /dev/null +++ b/Example/DApp/Connect/ConnectViewController.swift @@ -0,0 +1,54 @@ + +import Foundation +import UIKit + +class ConnectViewController: UIViewController { + let uriString: String + init(uri: String) { + self.uriString = uri + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private let connectView: ConnectView = { + ConnectView() + }() + + override func loadView() { + view = connectView + } + + override func viewDidLoad() { + super.viewDidLoad() + DispatchQueue.global().async { [unowned self] in + if let qrImage = generateQRCode(from: uriString) { + DispatchQueue.main.async { + connectView.qrCodeView.image = qrImage + connectView.copyButton.isHidden = false + } + } + } + connectView.copyButton.addTarget(self, action: #selector(copyURI), for: .touchUpInside) + connectView.copyButton.isHidden = true + } + + + @objc func copyURI() { + UIPasteboard.general.string = uriString + } + + + private func generateQRCode(from string: String) -> UIImage? { + let data = string.data(using: .ascii) + if let filter = CIFilter(name: "CIQRCodeGenerator") { + filter.setValue(data, forKey: "inputMessage") + if let output = filter.outputImage { + return UIImage(ciImage: output) + } + } + return nil + } +} diff --git a/Example/DApp/Info.plist b/Example/DApp/Info.plist index 9c3b929aa..994cd9071 100644 --- a/Example/DApp/Info.plist +++ b/Example/DApp/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Demo App + dApp CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier diff --git a/Example/DApp/SelectChain/SelectChainView.swift b/Example/DApp/SelectChain/SelectChainView.swift new file mode 100644 index 000000000..81891e15a --- /dev/null +++ b/Example/DApp/SelectChain/SelectChainView.swift @@ -0,0 +1,48 @@ + +import Foundation +import UIKit + + +class SelectChainView: UIView { + let tableView: UITableView = { + let tableView = UITableView(frame: .zero, style: .insetGrouped) + tableView.backgroundColor = .tertiarySystemBackground + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "chain") + return tableView + }() + let connectButton: UIButton = { + let button = UIButton(type: .system) + button.setTitle("Connect", for: .normal) + button.backgroundColor = .systemBlue + button.tintColor = .white + button.layer.cornerRadius = 8 + return button + }() + + override init(frame: CGRect) { + super.init(frame: frame) + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "chain_cell") + backgroundColor = .systemBackground + addSubview(tableView) + addSubview(connectButton) + + subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } + + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 16), + tableView.leadingAnchor.constraint(equalTo: leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: trailingAnchor), + tableView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor), + + connectButton.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -16), + connectButton.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor), + connectButton.heightAnchor.constraint(equalToConstant: 44), + connectButton.widthAnchor.constraint(equalToConstant: 120), + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + diff --git a/Example/DApp/SelectChainViewController.swift b/Example/DApp/SelectChain/SelectChainViewController.swift similarity index 55% rename from Example/DApp/SelectChainViewController.swift rename to Example/DApp/SelectChain/SelectChainViewController.swift index 5e69240b9..67fa3e014 100644 --- a/Example/DApp/SelectChainViewController.swift +++ b/Example/DApp/SelectChain/SelectChainViewController.swift @@ -8,6 +8,7 @@ struct Chain { let name: String let id: String } + class SelectChainViewController: UIViewController, UITableViewDataSource { private let selectChainView: SelectChainView = { SelectChainView() @@ -66,47 +67,3 @@ class SelectChainViewController: UIViewController, UITableViewDataSource { return cell } } - - -class SelectChainView: UIView { - let tableView: UITableView = { - let tableView = UITableView(frame: .zero, style: .insetGrouped) - tableView.backgroundColor = .tertiarySystemBackground - tableView.register(UITableViewCell.self, forCellReuseIdentifier: "chain") - return tableView - }() - let connectButton: UIButton = { - let button = UIButton(type: .system) - button.setTitle("Connect", for: .normal) - button.backgroundColor = .systemBlue - button.tintColor = .white - button.layer.cornerRadius = 8 - return button - }() - - override init(frame: CGRect) { - super.init(frame: frame) - tableView.register(UITableViewCell.self, forCellReuseIdentifier: "chain_cell") - backgroundColor = .systemBackground - addSubview(tableView) - addSubview(connectButton) - - subviews.forEach { $0.translatesAutoresizingMaskIntoConstraints = false } - - NSLayoutConstraint.activate([ - tableView.topAnchor.constraint(equalTo: safeAreaLayoutGuide.topAnchor, constant: 16), - tableView.leadingAnchor.constraint(equalTo: leadingAnchor), - tableView.trailingAnchor.constraint(equalTo: trailingAnchor), - tableView.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor), - - connectButton.bottomAnchor.constraint(equalTo: safeAreaLayoutGuide.bottomAnchor, constant: -16), - connectButton.centerXAnchor.constraint(equalTo: safeAreaLayoutGuide.centerXAnchor), - connectButton.heightAnchor.constraint(equalToConstant: 44), - connectButton.widthAnchor.constraint(equalToConstant: 120), - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/Example/DApp/ViewController.swift b/Example/DApp/ViewController.swift deleted file mode 100644 index 028a268db..000000000 --- a/Example/DApp/ViewController.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// ViewController.swift -// DApp -// -// Created by Admin on 19/01/2022. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view. - } - - -} - diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 3c26aea10..978d32ad3 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -28,12 +28,10 @@ 8460DD022750D7020081F94C /* SessionDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8460DD012750D7020081F94C /* SessionDetailsView.swift */; }; 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE641E27981DED00142511 /* AppDelegate.swift */; }; 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE642027981DED00142511 /* SceneDelegate.swift */; }; - 84CE642327981DED00142511 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE642227981DED00142511 /* ViewController.swift */; }; 84CE642827981DF000142511 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642727981DF000142511 /* Assets.xcassets */; }; 84CE642B27981DF000142511 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 84CE642927981DF000142511 /* LaunchScreen.storyboard */; }; 84CE6430279820F600142511 /* AccountsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761C649926FB7ABB004239D1 /* AccountsViewController.swift */; }; - 84CE6431279820F600142511 /* ProposerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7603D74C2703429A00DD27A2 /* ProposerView.swift */; }; - 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE64362798224900142511 /* ActivePairingItem.swift */; }; + 84CE6431279820F600142511 /* AccountsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7603D74C2703429A00DD27A2 /* AccountsView.swift */; }; 84CE64392798228D00142511 /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE64382798228D00142511 /* Web3 */; }; 84CE643B2798229100142511 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = 84CE643A2798229100142511 /* WalletConnect */; }; 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE643C2798322600142511 /* ConnectViewController.swift */; }; @@ -41,6 +39,8 @@ 84CE6446279ABBF300142511 /* ClientDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6445279ABBF300142511 /* ClientDelegate.swift */; }; 84CE6448279AE68600142511 /* AccountRequestViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6447279AE68600142511 /* AccountRequestViewController.swift */; }; 84CE644B279EA1FA00142511 /* AccountRequestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE644A279EA1FA00142511 /* AccountRequestView.swift */; }; + 84CE644E279ED2FF00142511 /* SelectChainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE644D279ED2FF00142511 /* SelectChainView.swift */; }; + 84CE6452279ED42B00142511 /* ConnectView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CE6451279ED42B00142511 /* ConnectView.swift */; }; 84F568C2279582D200D0A289 /* Signer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C1279582D200D0A289 /* Signer.swift */; }; 84F568C42795832A00D0A289 /* EthereumTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F568C32795832A00D0A289 /* EthereumTransaction.swift */; }; /* End PBXBuildFile section */ @@ -56,7 +56,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 7603D74C2703429A00DD27A2 /* ProposerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProposerView.swift; sourceTree = ""; }; + 7603D74C2703429A00DD27A2 /* AccountsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsView.swift; sourceTree = ""; }; 761C649926FB7ABB004239D1 /* AccountsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsViewController.swift; sourceTree = ""; }; 761C649B26FB7B7F004239D1 /* ResponderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponderViewController.swift; sourceTree = ""; wrapsLines = 0; }; 761C649D26FB7FD7004239D1 /* SessionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionViewController.swift; sourceTree = ""; }; @@ -84,16 +84,16 @@ 84CE641C27981DED00142511 /* DApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 84CE641E27981DED00142511 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 84CE642027981DED00142511 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; - 84CE642227981DED00142511 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 84CE642727981DF000142511 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 84CE642A27981DF000142511 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 84CE642C27981DF000142511 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 84CE64362798224900142511 /* ActivePairingItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivePairingItem.swift; sourceTree = ""; }; 84CE643C2798322600142511 /* ConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = ""; }; 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectChainViewController.swift; sourceTree = ""; }; 84CE6445279ABBF300142511 /* ClientDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientDelegate.swift; sourceTree = ""; }; 84CE6447279AE68600142511 /* AccountRequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRequestViewController.swift; sourceTree = ""; }; 84CE644A279EA1FA00142511 /* AccountRequestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountRequestView.swift; sourceTree = ""; }; + 84CE644D279ED2FF00142511 /* SelectChainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectChainView.swift; sourceTree = ""; }; + 84CE6451279ED42B00142511 /* ConnectView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectView.swift; sourceTree = ""; }; 84F568C1279582D200D0A289 /* Signer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signer.swift; sourceTree = ""; }; 84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = ""; }; /* End PBXFileReference section */ @@ -227,16 +227,13 @@ 84CE641D27981DED00142511 /* DApp */ = { isa = PBXGroup; children = ( - 84CE64362798224900142511 /* ActivePairingItem.swift */, 84CE641E27981DED00142511 /* AppDelegate.swift */, 84CE642027981DED00142511 /* SceneDelegate.swift */, - 84CE642227981DED00142511 /* ViewController.swift */, - 761C649926FB7ABB004239D1 /* AccountsViewController.swift */, 84CE6449279EA1E600142511 /* AccountRequest */, 84CE6445279ABBF300142511 /* ClientDelegate.swift */, - 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */, - 84CE643C2798322600142511 /* ConnectViewController.swift */, - 7603D74C2703429A00DD27A2 /* ProposerView.swift */, + 84CE644C279ED2EC00142511 /* SelectChain */, + 84CE6450279ED41D00142511 /* Connect */, + 84CE644F279ED3FB00142511 /* Accounts */, 84CE642727981DF000142511 /* Assets.xcassets */, 84CE642927981DF000142511 /* LaunchScreen.storyboard */, 84CE642C27981DF000142511 /* Info.plist */, @@ -253,6 +250,33 @@ path = AccountRequest; sourceTree = ""; }; + 84CE644C279ED2EC00142511 /* SelectChain */ = { + isa = PBXGroup; + children = ( + 84CE6443279AB5AD00142511 /* SelectChainViewController.swift */, + 84CE644D279ED2FF00142511 /* SelectChainView.swift */, + ); + path = SelectChain; + sourceTree = ""; + }; + 84CE644F279ED3FB00142511 /* Accounts */ = { + isa = PBXGroup; + children = ( + 761C649926FB7ABB004239D1 /* AccountsViewController.swift */, + 7603D74C2703429A00DD27A2 /* AccountsView.swift */, + ); + path = " Accounts"; + sourceTree = ""; + }; + 84CE6450279ED41D00142511 /* Connect */ = { + isa = PBXGroup; + children = ( + 84CE643C2798322600142511 /* ConnectViewController.swift */, + 84CE6451279ED42B00142511 /* ConnectView.swift */, + ); + path = Connect; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -426,13 +450,13 @@ files = ( 84CE6430279820F600142511 /* AccountsViewController.swift in Sources */, 84CE6446279ABBF300142511 /* ClientDelegate.swift in Sources */, - 84CE642327981DED00142511 /* ViewController.swift in Sources */, 84CE641F27981DED00142511 /* AppDelegate.swift in Sources */, + 84CE6452279ED42B00142511 /* ConnectView.swift in Sources */, 84CE6448279AE68600142511 /* AccountRequestViewController.swift in Sources */, 84CE642127981DED00142511 /* SceneDelegate.swift in Sources */, + 84CE644E279ED2FF00142511 /* SelectChainView.swift in Sources */, 84CE644B279EA1FA00142511 /* AccountRequestView.swift in Sources */, - 84CE6431279820F600142511 /* ProposerView.swift in Sources */, - 84CE64372798224900142511 /* ActivePairingItem.swift in Sources */, + 84CE6431279820F600142511 /* AccountsView.swift in Sources */, 84CE643D2798322600142511 /* ConnectViewController.swift in Sources */, 84CE6444279AB5AD00142511 /* SelectChainViewController.swift in Sources */, ); diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/DApp.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/DApp.xcscheme new file mode 100644 index 000000000..60a72b1ae --- /dev/null +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/DApp.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/ExampleApp/Info.plist b/Example/ExampleApp/Info.plist index 1fa4cd501..84b6f57d8 100644 --- a/Example/ExampleApp/Info.plist +++ b/Example/ExampleApp/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - Demo App + Wallet CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier From 49b2e3d2416ecfa90d50f69193f540fe193e0a05 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 13:47:11 +0100 Subject: [PATCH 17/19] Change schema name and display name --- .../xcschemes/IntegrationTests.xcscheme | 52 +++++++++++++++++++ Example/ExampleApp.xcodeproj/project.pbxproj | 22 ++++---- .../{ExampleApp.xcscheme => Wallet.xcscheme} | 8 +-- 3 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 .swiftpm/xcode/xcshareddata/xcschemes/IntegrationTests.xcscheme rename Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/{ExampleApp.xcscheme => Wallet.xcscheme} (94%) diff --git a/.swiftpm/xcode/xcshareddata/xcschemes/IntegrationTests.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/IntegrationTests.xcscheme new file mode 100644 index 000000000..0236cb7e7 --- /dev/null +++ b/.swiftpm/xcode/xcshareddata/xcschemes/IntegrationTests.xcscheme @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/ExampleApp.xcodeproj/project.pbxproj b/Example/ExampleApp.xcodeproj/project.pbxproj index 978d32ad3..110eb34a4 100644 --- a/Example/ExampleApp.xcodeproj/project.pbxproj +++ b/Example/ExampleApp.xcodeproj/project.pbxproj @@ -62,7 +62,7 @@ 761C649D26FB7FD7004239D1 /* SessionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionViewController.swift; sourceTree = ""; }; 761C64A226FB83CE004239D1 /* SessionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionView.swift; sourceTree = ""; }; 761C64A526FCB0AA004239D1 /* SessionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionInfo.swift; sourceTree = ""; }; - 764E1D3C26F8D3FC00A1FB15 /* ExampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ExampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 764E1D3C26F8D3FC00A1FB15 /* Wallet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Wallet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 764E1D3F26F8D3FC00A1FB15 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 764E1D4126F8D3FC00A1FB15 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; 764E1D4826F8D3FE00A1FB15 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -167,7 +167,7 @@ 764E1D3D26F8D3FC00A1FB15 /* Products */ = { isa = PBXGroup; children = ( - 764E1D3C26F8D3FC00A1FB15 /* ExampleApp.app */, + 764E1D3C26F8D3FC00A1FB15 /* Wallet.app */, 845B30EC27859686002E4094 /* ExampleAppTests.xctest */, 84CE641C27981DED00142511 /* DApp.app */, ); @@ -280,9 +280,9 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ - 764E1D3B26F8D3FC00A1FB15 /* ExampleApp */ = { + 764E1D3B26F8D3FC00A1FB15 /* Wallet */ = { isa = PBXNativeTarget; - buildConfigurationList = 764E1D5026F8D3FE00A1FB15 /* Build configuration list for PBXNativeTarget "ExampleApp" */; + buildConfigurationList = 764E1D5026F8D3FE00A1FB15 /* Build configuration list for PBXNativeTarget "Wallet" */; buildPhases = ( 764E1D3826F8D3FC00A1FB15 /* Sources */, 764E1D3926F8D3FC00A1FB15 /* Frameworks */, @@ -292,13 +292,13 @@ ); dependencies = ( ); - name = ExampleApp; + name = Wallet; packageProductDependencies = ( 764E1D5726F8DBAB00A1FB15 /* WalletConnect */, 844943A0278EC49700CC26BB /* Web3 */, ); productName = ExampleApp; - productReference = 764E1D3C26F8D3FC00A1FB15 /* ExampleApp.app */; + productReference = 764E1D3C26F8D3FC00A1FB15 /* Wallet.app */; productType = "com.apple.product-type.application"; }; 845B30EB27859686002E4094 /* ExampleAppTests */ = { @@ -377,7 +377,7 @@ projectDirPath = ""; projectRoot = ""; targets = ( - 764E1D3B26F8D3FC00A1FB15 /* ExampleApp */, + 764E1D3B26F8D3FC00A1FB15 /* Wallet */, 845B30EB27859686002E4094 /* ExampleAppTests */, 84CE641B27981DED00142511 /* DApp */, ); @@ -467,7 +467,7 @@ /* Begin PBXTargetDependency section */ 845B30F127859686002E4094 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 764E1D3B26F8D3FC00A1FB15 /* ExampleApp */; + target = 764E1D3B26F8D3FC00A1FB15 /* Wallet */; targetProxy = 845B30F027859686002E4094 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ @@ -672,7 +672,7 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ExampleApp.app/ExampleApp"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Wallet.app/Wallet"; }; name = Debug; }; @@ -692,7 +692,7 @@ SWIFT_EMIT_LOC_STRINGS = NO; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ExampleApp.app/ExampleApp"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Wallet.app/Wallet"; }; name = Release; }; @@ -768,7 +768,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 764E1D5026F8D3FE00A1FB15 /* Build configuration list for PBXNativeTarget "ExampleApp" */ = { + 764E1D5026F8D3FE00A1FB15 /* Build configuration list for PBXNativeTarget "Wallet" */ = { isa = XCConfigurationList; buildConfigurations = ( 764E1D5126F8D3FE00A1FB15 /* Debug */, diff --git a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/ExampleApp.xcscheme b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/Wallet.xcscheme similarity index 94% rename from Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/ExampleApp.xcscheme rename to Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/Wallet.xcscheme index dce1bdf8a..d9652ff9d 100644 --- a/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/ExampleApp.xcscheme +++ b/Example/ExampleApp.xcodeproj/xcshareddata/xcschemes/Wallet.xcscheme @@ -16,7 +16,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "764E1D3B26F8D3FC00A1FB15" BuildableName = "ExampleApp.app" - BlueprintName = "ExampleApp" + BlueprintName = "Wallet" ReferencedContainer = "container:ExampleApp.xcodeproj"> @@ -33,7 +33,7 @@ @@ -56,7 +56,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "764E1D3B26F8D3FC00A1FB15" BuildableName = "ExampleApp.app" - BlueprintName = "ExampleApp" + BlueprintName = "Wallet" ReferencedContainer = "container:ExampleApp.xcodeproj"> @@ -73,7 +73,7 @@ BuildableIdentifier = "primary" BlueprintIdentifier = "764E1D3B26F8D3FC00A1FB15" BuildableName = "ExampleApp.app" - BlueprintName = "ExampleApp" + BlueprintName = "Wallet" ReferencedContainer = "container:ExampleApp.xcodeproj"> From 674ff933f8edfc2cdd2e7f84b4ac3c6d542c521e Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Mon, 24 Jan 2022 14:12:59 +0100 Subject: [PATCH 18/19] fix fastflie --- Example/fastlane/Fastfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example/fastlane/Fastfile b/Example/fastlane/Fastfile index b63a04a84..1cdff6748 100644 --- a/Example/fastlane/Fastfile +++ b/Example/fastlane/Fastfile @@ -4,6 +4,6 @@ default_platform(:ios) platform :ios do desc "Test Example App" lane :test_app do - scan(xcargs: "-allowProvisioningUpdates") + scan(xcargs: "-allowProvisioningUpdates", scheme: "Wallet") end end From ba6b88816a29e2b362e3e132f10d298f6570d189 Mon Sep 17 00:00:00 2001 From: Bartosz Rozwarski Date: Thu, 27 Jan 2022 08:50:15 +0100 Subject: [PATCH 19/19] fix build --- Sources/WalletConnect/Relay/WalletConnectRelay.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/WalletConnect/Relay/WalletConnectRelay.swift b/Sources/WalletConnect/Relay/WalletConnectRelay.swift index 560e3dfa3..d384f0dbf 100644 --- a/Sources/WalletConnect/Relay/WalletConnectRelay.swift +++ b/Sources/WalletConnect/Relay/WalletConnectRelay.swift @@ -106,7 +106,7 @@ class WalletConnectRelay: WalletConnectRelaying { do { _ = try jsonRpcHistory.resolve(response: response) - let message = try jsonRpcSerialiser.serialise(topic: topic, encodable: response.value) + let message = try jsonRpcSerializer.serialize(topic: topic, encodable: response.value) logger.debug("Responding....topic: \(topic)") networkRelayer.publish(topic: topic, payload: message) { error in completion(error)