Skip to content

Commit

Permalink
Merge pull request #32 from WalletConnect/#19-tests-fix
Browse files Browse the repository at this point in the history
#19 fix integration test - add example app improvements
  • Loading branch information
llbartekll committed Jan 20, 2022
2 parents b3b53a7 + 7083b19 commit 4b71259
Show file tree
Hide file tree
Showing 28 changed files with 417 additions and 262 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/swift.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Swift

on:
push:
branches: [ main ]
branches: [ main, develop ]
pull_request:
branches: [ main ]
branches: [ main, develop ]

jobs:
build:
Expand Down
12 changes: 10 additions & 2 deletions Example/ExampleApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
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 */; };
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 */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -66,6 +68,8 @@
8460DCFB274F98A10081F94C /* RequestViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestViewController.swift; sourceTree = "<group>"; };
8460DCFF2750D6F50081F94C /* SessionDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailsViewController.swift; sourceTree = "<group>"; };
8460DD012750D7020081F94C /* SessionDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionDetailsView.swift; sourceTree = "<group>"; };
84F568C1279582D200D0A289 /* Signer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Signer.swift; sourceTree = "<group>"; };
84F568C32795832A00D0A289 /* EthereumTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumTransaction.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -92,6 +96,8 @@
isa = PBXGroup;
children = (
761C649B26FB7B7F004239D1 /* ResponderViewController.swift */,
84F568C32795832A00D0A289 /* EthereumTransaction.swift */,
84F568C1279582D200D0A289 /* Signer.swift */,
84494387278D9C1B00CC26BB /* UIAlertController.swift */,
76744CF426FDFB6B00B77ED9 /* ResponderView.swift */,
76744CF826FE4D7400B77ED9 /* ActiveSessionCell.swift */,
Expand Down Expand Up @@ -309,10 +315,12 @@
761C649E26FB7FD7004239D1 /* SessionViewController.swift in Sources */,
76744CF726FE4D5400B77ED9 /* ActiveSessionItem.swift in Sources */,
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 */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -469,7 +477,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
CURRENT_PROJECT_VERSION = 7;
DEVELOPMENT_TEAM = W5R8AG9K22;
INFOPLIST_FILE = ExampleApp/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
Expand All @@ -493,7 +501,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 2;
CURRENT_PROJECT_VERSION = 7;
DEVELOPMENT_TEAM = W5R8AG9K22;
INFOPLIST_FILE = ExampleApp/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
Expand Down
4 changes: 2 additions & 2 deletions Example/ExampleApp/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>Allow the app to scan for QR codes</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
Expand Down
17 changes: 17 additions & 0 deletions Example/ExampleApp/Responder/EthereumTransaction.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

import Foundation
import Web3

extension EthereumTransaction {
var description: String {
return """
from: \(String(describing: from!.hex(eip55: true)))
to: \(String(describing: to!.hex(eip55: true))),
value: \(String(describing: value!.hex())),
gasPrice: \(String(describing: gasPrice?.hex())),
gas: \(String(describing: gas?.hex())),
data: \(data.hex()),
nonce: \(String(describing: nonce?.hex()))
"""
}
}
83 changes: 16 additions & 67 deletions Example/ExampleApp/Responder/ResponderViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ final class ResponderViewController: UIViewController {
metadata: metadata,
projectId: "52af113ee0c1e1a20f4995730196c13e",
isController: true,
relayHost: "relay.dev.walletconnect.com",
relayHost: "relay.dev.walletconnect.com", //use with dapp at https://canary.react-app.walletconnect.com/
clientName: "responder"
)
}()
lazy var account = privateKey.address.hex(eip55: true)
lazy var account = Signer.privateKey.address.hex(eip55: true)
var sessionItems: [ActiveSessionItem] = []
var currentProposal: Session.Proposal?
let privateKey: EthereumPrivateKey = try! EthereumPrivateKey(hexPrivateKey: "0xe56da0e170b5e09a8bb8f1b693392c7d56c3739a9c75740fbc558a2877868540")

private let responderView: ResponderView = {
ResponderView()
Expand Down Expand Up @@ -69,29 +68,32 @@ final class ResponderViewController: UIViewController {
}

private func showSessionDetailsViewController(_ session: Session) {
let sessionInfo = SessionInfo(name: session.peer.name ?? "",
descriptionText: session.peer.description ?? "",
dappURL: session.peer.description ?? "",
iconURL: session.peer.icons?.first ?? "",
chains: Array(session.permissions.blockchains),
methods: Array(session.permissions.methods))
let vc = SessionDetailsViewController(sessionInfo)
let vc = SessionDetailsViewController(session, client)
navigationController?.pushViewController(vc, animated: true)
}

private func showSessionRequest(_ sessionRequest: Request) {
let requestVC = RequestViewController(sessionRequest)
requestVC.onSign = { [unowned self] in
let result = signEth(request: sessionRequest)
let result = Signer.signEth(request: sessionRequest)
let response = JSONRPCResponse<AnyCodable>(id: sessionRequest.id, result: result)
client.respond(topic: sessionRequest.topic, response: .response(response))
reloadSessionDetailsIfNeeded()
}
requestVC.onReject = { [weak self] in
self?.client.respond(topic: sessionRequest.topic, response: .error(JSONRPCErrorResponse(id: sessionRequest.id, error: JSONRPCErrorResponse.Error(code: 0, message: ""))))
requestVC.onReject = { [unowned self] in
client.respond(topic: sessionRequest.topic, response: .error(JSONRPCErrorResponse(id: sessionRequest.id, error: JSONRPCErrorResponse.Error(code: 0, message: ""))))
reloadSessionDetailsIfNeeded()
}
reloadSessionDetailsIfNeeded()
present(requestVC, animated: true)
}

func reloadSessionDetailsIfNeeded() {
if let sessionDetailsViewController = navigationController?.viewControllers.first(where: {$0 is SessionDetailsViewController}) as? SessionDetailsViewController {
sessionDetailsViewController.reloadTable()
}
}

private func pairClient(uri: String) {
print("[RESPONDER] Pairing to: \(uri)")
do {
Expand Down Expand Up @@ -173,7 +175,7 @@ extension ResponderViewController: WalletConnectClientDelegate {
dappURL: appMetadata.url ?? "",
iconURL: appMetadata.icons?.first ?? "",
chains: Array(sessionProposal.permissions.blockchains),
methods: Array(sessionProposal.permissions.methods))
methods: Array(sessionProposal.permissions.methods), pendingRequests: [])
currentProposal = sessionProposal
DispatchQueue.main.async { // FIXME: Delegate being called from background thread
self.showSessionProposal(info)
Expand Down Expand Up @@ -227,57 +229,4 @@ extension ResponderViewController: WalletConnectClientDelegate {
self.responderView.tableView.reloadData()
}
}

func signEth(request: Request) -> AnyCodable {
let method = request.method
if method == "personal_sign" {
let params = try! request.params.get([String].self)
let messageToSign = params[0]
let signHash = signHash(messageToSign)
let (v, r, s) = try! self.privateKey.sign(hash: signHash)
let result = "0x" + r.toHexString() + s.toHexString() + String(v + 27, radix: 16)
return AnyCodable(result)
} else if method == "eth_signTypedData" {
let params = try! request.params.get([String].self)
print(params)
let messageToSign = params[1]
let signHash = signHash(messageToSign)
let (v, r, s) = try! self.privateKey.sign(hash: signHash)
let result = "0x" + r.toHexString() + s.toHexString() + String(v + 27, radix: 16)
return AnyCodable(result)
} else if method == "eth_sendTransaction" {
let params = try! request.params.get([EthereumTransaction].self)
var transaction = params[0]
transaction.gas = EthereumQuantity(quantity: BigUInt("1234"))
print(transaction.description)
let signedTx = try! transaction.sign(with: self.privateKey, chainId: 4)
let (r, s, v) = (signedTx.r, signedTx.s, signedTx.v)
let result = r.hex() + s.hex().dropFirst(2) + String(v.quantity, radix: 16)
return AnyCodable(result)
}
fatalError("not implemented")
}

func signHash(_ message: String) -> Bytes {
let prefix = "\u{19}Ethereum Signed Message:\n"
let messageData = Data(hex: message)
let prefixData = (prefix + String(messageData.count)).data(using: .utf8)!
let prefixedMessageData = prefixData + messageData
let dataToHash: Bytes = .init(hex: prefixedMessageData.toHexString())
return SHA3(variant: .keccak256).calculate(for: dataToHash)
}
}

extension EthereumTransaction {
var description: String {
return """
from: \(String(describing: from!.hex(eip55: true)))
to: \(String(describing: to!.hex(eip55: true))),
value: \(String(describing: value!.hex())),
gasPrice: \(String(describing: gasPrice?.hex())),
gas: \(String(describing: gas?.hex())),
data: \(data.hex()),
nonce: \(String(describing: nonce?.hex()))
"""
}
}
26 changes: 1 addition & 25 deletions Example/ExampleApp/Responder/SessionProposal/SessionInfo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,5 @@ struct SessionInfo {
let iconURL: String
let chains: [String]
let methods: [String]
}

extension SessionInfo {

static func mock() -> SessionInfo {
SessionInfo(
name: "Dapp Name",
descriptionText: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris at eleifend est, vel porta enim. Praesent non placerat orci. Curabitur orci sem, molestie feugiat enim eu, tincidunt tincidunt est.",
dappURL: "decentralized.finance",
iconURL: "https://s2.coinmarketcap.com/static/img/coins/64x64/1.png",
chains: ["Ethereum Kovan", "BSC Mainnet", "Fantom Opera"],
methods: ["personal_sign", "eth_sendTransaction", "eth_signTypedData"]
)
}

static func mockPancakeSwap() -> SessionInfo {
SessionInfo(
name: "🥞 PancakeSwap",
descriptionText: "Cheaper and faster than Uniswap? Discover PancakeSwap, the leading DEX on Binance Smart Chain (BSC) with the best farms in DeFi and a lottery for CAKE.",
dappURL: "pancakeswap.finance",
iconURL: "https://pancakeswap.finance/logo.png",
chains: ["Binance Smart Chain (BSC)"],
methods: ["personal_sign"]
)
}
let pendingRequests: [String]
}
48 changes: 48 additions & 0 deletions Example/ExampleApp/Responder/Signer.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Web3
import Foundation
import WalletConnectUtils
import WalletConnect
import CryptoSwift

class Signer {
static let privateKey: EthereumPrivateKey = try! EthereumPrivateKey(hexPrivateKey: "0xe56da0e170b5e09a8bb8f1b693392c7d56c3739a9c75740fbc558a2877868540")
private init(){}
static func signEth(request: Request) -> AnyCodable {
let method = request.method
if method == "personal_sign" {
let params = try! request.params.get([String].self)
let messageToSign = params[0]
let signHash = signHash(messageToSign)
let (v, r, s) = try! self.privateKey.sign(hash: signHash)
let result = "0x" + r.toHexString() + s.toHexString() + String(v + 27, radix: 16)
return AnyCodable(result)
} else if method == "eth_signTypedData" {
let params = try! request.params.get([String].self)
print(params)
let messageToSign = params[1]
let signHash = signHash(messageToSign)
let (v, r, s) = try! self.privateKey.sign(hash: signHash)
let result = "0x" + r.toHexString() + s.toHexString() + String(v + 27, radix: 16)
return AnyCodable(result)
} else if method == "eth_sendTransaction" {
let params = try! request.params.get([EthereumTransaction].self)
var transaction = params[0]
transaction.gas = EthereumQuantity(quantity: BigUInt("1234"))
print(transaction.description)
let signedTx = try! transaction.sign(with: self.privateKey, chainId: 4)
let (r, s, v) = (signedTx.r, signedTx.s, signedTx.v)
let result = r.hex() + s.hex().dropFirst(2) + String(v.quantity, radix: 16)
return AnyCodable(result)
}
fatalError("not implemented")
}

private static func signHash(_ message: String) -> Bytes {
let prefix = "\u{19}Ethereum Signed Message:\n"
let messageData = Data(hex: message)
let prefixData = (prefix + String(messageData.count)).data(using: .utf8)!
let prefixedMessageData = prefixData + messageData
let dataToHash: Bytes = .init(hex: prefixedMessageData.toHexString())
return SHA3(variant: .keccak256).calculate(for: dataToHash)
}
}
2 changes: 1 addition & 1 deletion Example/ExampleApp/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ extension UITabBarController {
let proposerController = UINavigationController(rootViewController: ProposerViewController())
proposerController.tabBarItem = UITabBarItem(title: "Dapp", image: UIImage(systemName: "appclip"), selectedImage: nil)
let tabBarController = UITabBarController()
tabBarController.viewControllers = [responderController, proposerController]
tabBarController.viewControllers = [responderController]
return tabBarController
}
}
Loading

0 comments on commit 4b71259

Please sign in to comment.