Skip to content

Commit

Permalink
Merge pull request #73 from WalletConnect/1click-auth
Browse files Browse the repository at this point in the history
1click auth and link mode integration
  • Loading branch information
llbartekll authored Jun 4, 2024
2 parents 030dad9 + aa012ee commit e7708e3
Show file tree
Hide file tree
Showing 17 changed files with 276 additions and 111 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let package = Package(
dependencies: [
.package(
url: "https://github.com/WalletConnect/WalletConnectSwiftV2",
.upToNextMinor(from: "1.13.0")
.upToNextMinor(from: "1.19.1")
),
.package(
url: "https://github.com/WalletConnect/QRCode",
Expand Down
52 changes: 41 additions & 11 deletions Sample/Example.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@

/* Begin PBXBuildFile section */
23F6FD03919B41DE98CAFCD3 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = BD206AA550964C49AE94A3CA /* Sentry */; };
84D9CCC32B9708E4001EDEE3 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = 84D9CCC22B9708E4001EDEE3 /* Starscream */; };
84F3EFBB2BA86FA6005FCFAE /* DefaultCryptoProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84F3EFBA2BA86FA6005FCFAE /* DefaultCryptoProvider.swift */; };
84F3EFBE2BA87760005FCFAE /* Web3 in Frameworks */ = {isa = PBXBuildFile; productRef = 84F3EFBD2BA87760005FCFAE /* Web3 */; };
84F3EFC02BA87760005FCFAE /* Web3ContractABI in Frameworks */ = {isa = PBXBuildFile; productRef = 84F3EFBF2BA87760005FCFAE /* Web3ContractABI */; };
84F3EFC22BA87760005FCFAE /* Web3PromiseKit in Frameworks */ = {isa = PBXBuildFile; productRef = 84F3EFC12BA87760005FCFAE /* Web3PromiseKit */; };
84FEB1382C0DAE210018CB53 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = 84FEB1372C0DAE210018CB53 /* Starscream */; };
CF0BCCE52AB0886400A2866C /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF0BCCE42AB0886400A2866C /* ContentView.swift */; };
CF25F3A22B40C7070030B3DC /* Web3Modal in Frameworks */ = {isa = PBXBuildFile; productRef = CF25F3A12B40C7070030B3DC /* Web3Modal */; };
CF25F3A42B40C7070030B3DC /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = CF25F3A32B40C7070030B3DC /* Web3ModalUI */; };
CF3B9AD02ACDBA3A00984D53 /* Web3Modal in Frameworks */ = {isa = PBXBuildFile; productRef = CF3B9ACF2ACDBA3A00984D53 /* Web3Modal */; };
CF3B9AD22ACDBA3A00984D53 /* Web3ModalUI in Frameworks */ = {isa = PBXBuildFile; productRef = CF3B9AD12ACDBA3A00984D53 /* Web3ModalUI */; };
CFA99B922AD0549F00EB5331 /* WCSocketFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFA99B912AD0549F00EB5331 /* WCSocketFactory.swift */; };
CFD6A70F2ADE8DE2002B402C /* Atlantis in Frameworks */ = {isa = PBXBuildFile; productRef = CFD6A70E2ADE8DE2002B402C /* Atlantis */; };
Expand All @@ -24,6 +27,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
84F3EFBA2BA86FA6005FCFAE /* DefaultCryptoProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultCryptoProvider.swift; sourceTree = "<group>"; };
CF0BCCE42AB0886400A2866C /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
CF533D032ADD411A00B3441C /* web3modal-swift */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "web3modal-swift"; path = ..; sourceTree = "<group>"; };
CF74C5C62B323048007B0926 /* swift-web3modal-Package.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "swift-web3modal-Package.xctestplan"; sourceTree = "<group>"; };
Expand All @@ -44,13 +48,15 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
84D9CCC32B9708E4001EDEE3 /* Starscream in Frameworks */,
CF3B9AD02ACDBA3A00984D53 /* Web3Modal in Frameworks */,
CFD6A70F2ADE8DE2002B402C /* Atlantis in Frameworks */,
84F3EFC02BA87760005FCFAE /* Web3ContractABI in Frameworks */,
CF25F3A42B40C7070030B3DC /* Web3ModalUI in Frameworks */,
CF3B9AD22ACDBA3A00984D53 /* Web3ModalUI in Frameworks */,
84F3EFBE2BA87760005FCFAE /* Web3 in Frameworks */,
CF25F3A22B40C7070030B3DC /* Web3Modal in Frameworks */,
84F3EFC22BA87760005FCFAE /* Web3PromiseKit in Frameworks */,
23F6FD03919B41DE98CAFCD3 /* Sentry in Frameworks */,
84FEB1382C0DAE210018CB53 /* Starscream in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -82,6 +88,7 @@
CFD6A7102ADE8E26002B402C /* Info.plist */,
CFA99B912AD0549F00EB5331 /* WCSocketFactory.swift */,
CFD720772A9CC60600636CAF /* ExampleApp.swift */,
84F3EFBA2BA86FA6005FCFAE /* DefaultCryptoProvider.swift */,
CFD720792A9CC60600636CAF /* ComponentLibraryView.swift */,
CFEAAF082B6C0A58001565F5 /* Configuration.xcconfig */,
CF0BCCE42AB0886400A2866C /* ContentView.swift */,
Expand Down Expand Up @@ -126,13 +133,15 @@
);
name = Example;
packageProductDependencies = (
CF3B9ACF2ACDBA3A00984D53 /* Web3Modal */,
CF3B9AD12ACDBA3A00984D53 /* Web3ModalUI */,
CFD6A70E2ADE8DE2002B402C /* Atlantis */,
BD206AA550964C49AE94A3CA /* Sentry */,
CF25F3A12B40C7070030B3DC /* Web3Modal */,
CF25F3A32B40C7070030B3DC /* Web3ModalUI */,
84D9CCC22B9708E4001EDEE3 /* Starscream */,
84F3EFBD2BA87760005FCFAE /* Web3 */,
84F3EFBF2BA87760005FCFAE /* Web3ContractABI */,
84F3EFC12BA87760005FCFAE /* Web3PromiseKit */,
84FEB1372C0DAE210018CB53 /* Starscream */,
);
productName = Example;
productReference = CFD720742A9CC60600636CAF /* Example.app */;
Expand Down Expand Up @@ -167,6 +176,7 @@
CF25F3A02B40C7070030B3DC /* XCLocalSwiftPackageReference ".." */,
F4A0329B6CFF49E682D3DFE7 /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
84D9CCC12B9708E4001EDEE3 /* XCRemoteSwiftPackageReference "Starscream" */,
84F3EFBC2BA87760005FCFAE /* XCRemoteSwiftPackageReference "Web3" */,
);
productRefGroup = CFD720752A9CC60600636CAF /* Products */;
projectDirPath = "";
Expand Down Expand Up @@ -217,6 +227,7 @@
CFD720782A9CC60600636CAF /* ExampleApp.swift in Sources */,
CF0BCCE52AB0886400A2866C /* ContentView.swift in Sources */,
CFA99B922AD0549F00EB5331 /* WCSocketFactory.swift in Sources */,
84F3EFBB2BA86FA6005FCFAE /* DefaultCryptoProvider.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -480,6 +491,14 @@
minimumVersion = 3.1.2;
};
};
84F3EFBC2BA87760005FCFAE /* XCRemoteSwiftPackageReference "Web3" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/WalletConnect/Web3.swift";
requirement = {
kind = exactVersion;
version = 1.0.2;
};
};
CFD6A70D2ADE8DE2002B402C /* XCRemoteSwiftPackageReference "atlantis" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/ProxymanApp/atlantis";
Expand All @@ -499,7 +518,22 @@
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
84D9CCC22B9708E4001EDEE3 /* Starscream */ = {
84F3EFBD2BA87760005FCFAE /* Web3 */ = {
isa = XCSwiftPackageProductDependency;
package = 84F3EFBC2BA87760005FCFAE /* XCRemoteSwiftPackageReference "Web3" */;
productName = Web3;
};
84F3EFBF2BA87760005FCFAE /* Web3ContractABI */ = {
isa = XCSwiftPackageProductDependency;
package = 84F3EFBC2BA87760005FCFAE /* XCRemoteSwiftPackageReference "Web3" */;
productName = Web3ContractABI;
};
84F3EFC12BA87760005FCFAE /* Web3PromiseKit */ = {
isa = XCSwiftPackageProductDependency;
package = 84F3EFBC2BA87760005FCFAE /* XCRemoteSwiftPackageReference "Web3" */;
productName = Web3PromiseKit;
};
84FEB1372C0DAE210018CB53 /* Starscream */ = {
isa = XCSwiftPackageProductDependency;
package = 84D9CCC12B9708E4001EDEE3 /* XCRemoteSwiftPackageReference "Starscream" */;
productName = Starscream;
Expand All @@ -517,10 +551,6 @@
isa = XCSwiftPackageProductDependency;
productName = Web3ModalUI;
};
CF3B9ACF2ACDBA3A00984D53 /* Web3Modal */ = {
isa = XCSwiftPackageProductDependency;
productName = Web3Modal;
};
CF3B9AD12ACDBA3A00984D53 /* Web3ModalUI */ = {
isa = XCSwiftPackageProductDependency;
productName = Web3ModalUI;
Expand Down
28 changes: 15 additions & 13 deletions Sample/Example/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ struct ContentView: View {
Web3ModalNetworkButton()

Spacer()

Button("Personal sign") {
requestPersonalSign()
Web3Modal.instance.launchCurrentWallet()
Task {
do {
try await requestPersonalSign()
Web3Modal.instance.launchCurrentWallet()
} catch {
print("Error occurred: \(error)")
}
}
}
.buttonStyle(W3MButtonStyle())

NavigationLink(destination: ComponentLibraryView(), isActive: $showUIComponents) {
Button("UI components") {
showUIComponents = true
Expand All @@ -45,14 +51,10 @@ struct ContentView: View {
}
}

func requestPersonalSign() {
Task {
do {
guard let address = Web3Modal.instance.getAddress() else { return }
try await Web3Modal.instance.request(.personal_sign(address: address, message: "Hello there!"))
} catch {
print(error)
}
}
func requestPersonalSign() async throws {

guard let address = Web3Modal.instance.getAddress() else { return }
try await Web3Modal.instance.request(.personal_sign(address: address, message: "Hello there!"))

}
}
24 changes: 24 additions & 0 deletions Sample/Example/DefaultCryptoProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation
import Web3
import CryptoSwift
import WalletConnectSigner

struct DefaultCryptoProvider: CryptoProvider {

public func recoverPubKey(signature: EthereumSignature, message: Data) throws -> Data {
let publicKey = try EthereumPublicKey(
message: message.bytes,
v: EthereumQuantity(quantity: BigUInt(signature.v)),
r: EthereumQuantity(signature.r),
s: EthereumQuantity(signature.s)
)
return Data(publicKey.rawPublicKey)
}

public func keccak256(_ data: Data) -> Data {
let digest = SHA3(variant: .keccak256)
let hash = digest.calculate(for: [UInt8](data))
return Data(hash)
}

}
4 changes: 4 additions & 0 deletions Sample/Example/Example.entitlements
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:lab.web3modal.com</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
Expand Down
51 changes: 43 additions & 8 deletions Sample/Example/ExampleApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ExampleApp: App {
description: "Web3Modal DApp sample",
url: "www.web3modal.com",
icons: ["https://avatars.githubusercontent.com/u/37784886"],
redirect: .init(native: "w3mdapp://", universal: nil)
redirect: try! .init(native: "w3mdapp://", universal: "https://lab.web3modal.com/web3modal_example", linkMode: true)
)

Networking.configure(
Expand All @@ -57,21 +57,25 @@ class ExampleApp: App {
Web3Modal.configure(
projectId: projectId,
metadata: metadata,
crypto: DefaultCryptoProvider(),
authRequestParams: .stub(),
customWallets: [
.init(
id: "swift-sample",
name: "Swift Sample Wallet",
homepage: "https://walletconnect.com/",
imageUrl: "https://avatars.githubusercontent.com/u/37784886?s=200&v=4",
order: 1,
mobileLink: "walletapp://"
)
id: "swift-sample",
name: "Swift Sample Wallet",
homepage: "https://walletconnect.com/",
imageUrl: "https://avatars.githubusercontent.com/u/37784886?s=200&v=4",
order: 1,
mobileLink: "walletapp://",
linkMode: "https://lab.web3modal.com/wallet"
)
]
) { error in
SentrySDK.capture(error: error)

print(error)
}

setup()

}
Expand All @@ -83,6 +87,9 @@ class ExampleApp: App {

}.store(in: &disposeBag)
Web3Modal.instance.logger.setLogging(level: .debug)
Sign.instance.setLogging(level: .debug)
Networking.instance.setLogging(level: .debug)
Relay.instance.setLogging(level: .debug)
}

var body: some Scene {
Expand Down Expand Up @@ -114,3 +121,31 @@ class ExampleApp: App {
}
}
}

extension AuthRequestParams {
static func stub(
domain: String = "lab.web3modal.com",
chains: [String] = ["eip155:1", "eip155:137"],
nonce: String = "32891756",
uri: String = "https://lab.web3modal.com",
nbf: String? = nil,
exp: String? = nil,
statement: String? = "I accept the ServiceOrg Terms of Service: https://lab.web3modal.com",
requestId: String? = nil,
resources: [String]? = nil,
methods: [String]? = ["personal_sign", "eth_sendTransaction"]
) -> AuthRequestParams {
return try! AuthRequestParams(
domain: domain,
chains: chains,
nonce: nonce,
uri: uri,
nbf: nbf,
exp: exp,
statement: statement,
requestId: requestId,
resources: resources,
methods: methods
)
}
}
10 changes: 6 additions & 4 deletions Sources/Web3Modal/Core/SignInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,16 @@ class SignInteractor: ObservableObject {
lazy var sessionRejectionPublisher: AnyPublisher<(Session.Proposal, Reason), Never> = Web3Modal.instance.sessionRejectionPublisher
lazy var sessionDeletePublisher: AnyPublisher<(String, Reason), Never> = Web3Modal.instance.sessionDeletePublisher
lazy var sessionEventPublisher: AnyPublisher<(event: Session.Event, sessionTopic: String, chainId: Blockchain?), Never> = Web3Modal.instance.sessionEventPublisher

lazy var authResponsePublisher: AnyPublisher<(id: RPCID, result: Result<(Session?, [Cacao]), AuthError>), Never> = Web3Modal.instance.authResponsePublisher


init(store: Store = .shared) {
self.store = store
}

func createPairingAndConnect() async throws {
let uri = try await Web3Modal.instance.connect(topic: nil)
func connect(walletUniversalLink: String?) async throws {
let uri = try await Web3Modal.instance.connect(walletUniversalLink: walletUniversalLink)

DispatchQueue.main.async {
self.store.uri = uri
self.store.retryShown = false
Expand Down
18 changes: 14 additions & 4 deletions Sources/Web3Modal/Core/Web3Modal.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,18 @@ public class Web3Modal {

let projectId: String
var metadata: AppMetadata
let crypto: CryptoProvider
var sessionParams: SessionParams

var authRequestParams: AuthRequestParams?

let includeWebWallets: Bool
let recommendedWalletIds: [String]
let excludedWalletIds: [String]
let customWallets: [Wallet]
let coinbaseEnabled: Bool

let onError: (Error) -> Void

}

private(set) static var config: Config!
Expand All @@ -91,7 +94,9 @@ public class Web3Modal {
public static func configure(
projectId: String,
metadata: AppMetadata,
crypto: CryptoProvider,
sessionParams: SessionParams = .default,
authRequestParams: AuthRequestParams?,
includeWebWallets: Bool = true,
recommendedWalletIds: [String] = [],
excludedWalletIds: [String] = [],
Expand All @@ -104,15 +109,19 @@ public class Web3Modal {
Web3Modal.config = Web3Modal.Config(
projectId: projectId,
metadata: metadata,
crypto: crypto,
sessionParams: sessionParams,
authRequestParams: authRequestParams,
includeWebWallets: includeWebWallets,
recommendedWalletIds: recommendedWalletIds,
excludedWalletIds: excludedWalletIds,
customWallets: customWallets,
coinbaseEnabled: coinbaseEnabled,
onError: onError
)


Sign.configure(crypto: crypto)

let store = Store.shared
let router = Router()
let w3mApiInteractor = W3MAPIInteractor(store: store)
Expand Down Expand Up @@ -169,6 +178,7 @@ public class Web3Modal {
imageId: "a5ebc364-8f91-4200-fcc6-be81310a0000",
order: 4,
mobileLink: nil,
linkMode: nil,
desktopLink: nil,
webappLink: nil,
appStore: "https://apps.apple.com/us/app/coinbase-wallet-nfts-crypto/id1278383455",
Expand Down Expand Up @@ -305,8 +315,8 @@ public struct SessionParams {
public static let `default`: Self = {
let methods: Set<String> = Set(EthUtils.ethMethods)
let events: Set<String> = ["chainChanged", "accountsChanged"]
let blockchains: Set<Blockchain> = Set(ChainPresets.ethChains.map(\.id).compactMap(Blockchain.init))
let blockchains = ChainPresets.ethChains.map(\.id).compactMap(Blockchain.init)

let namespaces: [String: ProposalNamespace] = [
"eip155": ProposalNamespace(
chains: blockchains,
Expand Down
Loading

0 comments on commit e7708e3

Please sign in to comment.