Skip to content

Commit

Permalink
Merge pull request #1252 from WalletConnect/feature/notify-isregistered
Browse files Browse the repository at this point in the history
[Notify] Registration api update
  • Loading branch information
flypaper0 authored Dec 8, 2023
2 parents 8b2e3c2 + b82e750 commit ebe4f86
Show file tree
Hide file tree
Showing 11 changed files with 127 additions and 118 deletions.
13 changes: 11 additions & 2 deletions Example/IntegrationTests/Push/NotifyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,17 @@ final class NotifyTests: XCTestCase {


private extension NotifyTests {
func sign(_ message: String) -> SigningResult {
func sign(_ message: String) -> CacaoSignature {
let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId)
return .signed(try! signer.sign(message: message, privateKey: privateKey, type: .eip191))
return try! signer.sign(message: message, privateKey: privateKey, type: .eip191)
}
}

private extension NotifyClient {

func register(account: Account, domain: String, isLimited: Bool = false, onSign: @escaping (String) -> CacaoSignature) async throws {
let params = try await prepareRegistration(account: account, domain: domain)
let signature = onSign(params.message)
try await register(params: params, signature: signature)
}
}
4 changes: 2 additions & 2 deletions Example/Shared/ImportAccount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ enum ImportAccount: Codable {
}
}

func onSign(message: String) -> SigningResult {
func onSign(message: String) -> CacaoSignature {
let privateKey = Data(hex: privateKey)
let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create()
let signature = try! signer.sign(message: message, privateKey: privateKey, type: .eip191)
return .signed(signature)
return signature
}

static func new() -> ImportAccount {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ final class ConfigurationService {

Task {
do {
try await Notify.instance.register(account: importAccount.account, domain: "com.walletconnect", onSign: importAccount.onSign)
let params = try await Notify.instance.prepareRegistration(account: importAccount.account, domain: "com.walletconnect")
let signature = importAccount.onSign(message: params.message)
try await Notify.instance.register(params: params, signature: signature)
} catch {
DispatchQueue.main.async {
let logMessage = LogMessage(message: "Push Server registration failed with: \(error.localizedDescription)")
Expand Down
33 changes: 21 additions & 12 deletions Sources/Chat/ChatClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,34 @@ public class ChatClient {
domain: String,
onSign: @escaping SigningCallback
) async throws -> String {
let publicKey = try await identityClient.register(

let params = try await identityClient.prepareRegistration(
account: account,
domain: domain,
statement: "statement",
resources: ["https://keys.walletconnect.com"],
onSign: onSign
resources: ["https://keys.walletconnect.com"]
)
if !syncRegisterService.isRegistered(account: account) {
try await chatStorage.initializeHistory(account: account)
try await syncRegisterService.register(account: account, onSign: onSign)
}

guard !isPrivate else {
return publicKey
}
switch await onSign(params.message) {
case .signed(let signature):
let publicKey = try await identityClient.register(params: params, signature: signature)

if !syncRegisterService.isRegistered(account: account) {
try await chatStorage.initializeHistory(account: account)
try await syncRegisterService.register(account: account, onSign: onSign)
}

try await goPublic(account: account)
guard !isPrivate else {
return publicKey
}

return publicKey
try await goPublic(account: account)

return publicKey

case .rejected:
fatalError("Not implemented")
}
}

/// Unregisters a blockchain account with previously registered identity key
Expand Down
16 changes: 14 additions & 2 deletions Sources/WalletConnectIdentity/IdentityClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,20 @@ public final class IdentityClient {
self.logger = logger
}

public func register(account: Account, domain: String, statement: String, resources: [String], onSign: SigningCallback) async throws -> String {
let pubKey = try await identityService.registerIdentity(account: account, domain: domain, statement: statement, resources: resources, onSign: onSign)
public func prepareRegistration(account: Account,
domain: String,
statement: String,
resources: [String]) async throws -> IdentityRegistrationParams
{
let registration = try await identityService.prepareRegistration(account: account, domain: domain, statement: statement, resources: resources)
logger.debug("Did prepare registration for \(account)")
return registration
}

@discardableResult
public func register(params: IdentityRegistrationParams, signature: CacaoSignature) async throws -> String {
let account = try params.account
let pubKey = try await identityService.registerIdentity(params: params, signature: signature)
logger.debug("Did register an account: \(account)")
return pubKey
}
Expand Down
5 changes: 0 additions & 5 deletions Sources/WalletConnectIdentity/IdentityError.swift

This file was deleted.

11 changes: 11 additions & 0 deletions Sources/WalletConnectIdentity/IdentityRegistrationParams.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

public struct IdentityRegistrationParams {
public let message: String
public let payload: CacaoPayload
public let privateIdentityKey: SigningPrivateKey

public var account: Account {
get throws { try Account(DIDPKHString: payload.iss) }
}
}
71 changes: 31 additions & 40 deletions Sources/WalletConnectIdentity/IdentityService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,46 @@ actor IdentityService {
self.messageFormatter = messageFormatter
}

func registerIdentity(account: Account,
func prepareRegistration(account: Account,
domain: String,
statement: String,
resources: [String],
onSign: SigningCallback
) async throws -> String {
resources: [String]) throws -> IdentityRegistrationParams {

let identityKey = SigningPrivateKey()

let payload = CacaoPayload(
iss: account.did,
domain: domain,
aud: identityKey.publicKey.did,
version: getVersion(),
nonce: getNonce(),
iat: iatProvader.iat,
nbf: nil, exp: nil,
statement: statement,
requestId: nil,
resources: resources
)

let message = try messageFormatter.formatMessage(from: payload)

return IdentityRegistrationParams(message: message, payload: payload, privateIdentityKey: identityKey)
}

// TODO: Verifications
func registerIdentity(params: IdentityRegistrationParams, signature: CacaoSignature) async throws -> String {
let account = try params.account

if let identityKey = try? storage.getIdentityKey(for: account) {
return identityKey.publicKey.hexRepresentation
}

let identityKey = SigningPrivateKey()
let audience = identityKey.publicKey.did
let cacao = try await makeCacao(account: account, domain: domain, statement: statement, resources: resources, audience: audience, onSign: onSign)
let cacaoHeader = CacaoHeader(t: "eip4361")
let cacao = Cacao(h: cacaoHeader, p: params.payload, s: signature)

try await networkService.registerIdentity(cacao: cacao)
try storage.saveIdentityKey(params.privateIdentityKey, for: account)

return try storage.saveIdentityKey(identityKey, for: account).publicKey.hexRepresentation
return params.privateIdentityKey.publicKey.hexRepresentation
}

func registerInvite(account: Account) async throws -> AgreementPublicKey {
Expand Down Expand Up @@ -89,38 +112,6 @@ actor IdentityService {

private extension IdentityService {

func makeCacao(account: Account,
domain: String,
statement: String,
resources: [String],
audience: String,
onSign: SigningCallback
) async throws -> Cacao {

let cacaoHeader = CacaoHeader(t: "eip4361")
let cacaoPayload = CacaoPayload(
iss: account.did,
domain: domain,
aud: audience,
version: getVersion(),
nonce: getNonce(),
iat: iatProvader.iat,
nbf: nil, exp: nil,
statement: statement,
requestId: nil,
resources: resources
)

let result = await onSign(try messageFormatter.formatMessage(from: cacaoPayload))

switch result {
case .signed(let cacaoSignature):
return Cacao(h: cacaoHeader, p: cacaoPayload, s: cacaoSignature)
case .rejected:
throw IdentityError.signatureRejected
}
}

func makeIDAuth<Claims: IDAuthClaims>(account: Account, issuer: DIDKey, claims: Claims.Type) throws -> String {
let identityKey = try storage.getIdentityKey(for: account)

Expand Down
40 changes: 32 additions & 8 deletions Sources/WalletConnectNotify/Client/Wallet/NotifyClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ public class NotifyClient {

public let logger: ConsoleLogging

private let keyserverURL: URL
private let pushClient: PushClient
private let identityService: NotifyIdentityService
private let identityClient: IdentityClient
private let notifyStorage: NotifyStorage
private let notifyAccountProvider: NotifyAccountProvider
private let notifyMessageSubscriber: NotifyMessageSubscriber
Expand All @@ -38,8 +39,9 @@ public class NotifyClient {
private let subscriptionWatcher: SubscriptionWatcher

init(logger: ConsoleLogging,
keyserverURL: URL,
kms: KeyManagementServiceProtocol,
identityService: NotifyIdentityService,
identityClient: IdentityClient,
pushClient: PushClient,
notifyMessageSubscriber: NotifyMessageSubscriber,
notifyStorage: NotifyStorage,
Expand All @@ -57,8 +59,9 @@ public class NotifyClient {
subscriptionWatcher: SubscriptionWatcher
) {
self.logger = logger
self.keyserverURL = keyserverURL
self.pushClient = pushClient
self.identityService = identityService
self.identityClient = identityClient
self.notifyMessageSubscriber = notifyMessageSubscriber
self.notifyStorage = notifyStorage
self.deleteNotifySubscriptionRequester = deleteNotifySubscriptionRequester
Expand All @@ -75,14 +78,23 @@ public class NotifyClient {
self.subscriptionWatcher = subscriptionWatcher
}

public func register(account: Account, domain: String, isLimited: Bool = false, onSign: @escaping SigningCallback) async throws {
try await identityService.register(account: account, domain: domain, isLimited: isLimited, onSign: onSign)
notifyAccountProvider.setAccount(account)
public func prepareRegistration(account: Account, domain: String, allApps: Bool = true) async throws -> IdentityRegistrationParams {
return try await identityClient.prepareRegistration(
account: account,
domain: domain,
statement: makeStatement(allApps: allApps),
resources: [keyserverURL.absoluteString]
)
}

public func register(params: IdentityRegistrationParams, signature: CacaoSignature) async throws {
try await identityClient.register(params: params, signature: signature)
notifyAccountProvider.setAccount(try params.account)
try await subscriptionWatcher.start()
}

public func unregister(account: Account) async throws {
try await identityService.unregister(account: account)
try await identityClient.unregister(account: account)
notifyWatcherAgreementKeysProvider.removeAgreement(account: account)
try notifyStorage.clearDatabase(account: account)
notifyAccountProvider.logout()
Expand Down Expand Up @@ -122,7 +134,7 @@ public class NotifyClient {
}

public func isIdentityRegistered(account: Account) -> Bool {
return identityService.isIdentityRegistered(account: account)
return identityClient.isIdentityRegistered(account: account)
}

public func subscriptionsPublisher(account: Account) -> AnyPublisher<[NotifySubscription], Never> {
Expand All @@ -134,6 +146,18 @@ public class NotifyClient {
}
}

private extension NotifyClient {

func makeStatement(allApps: Bool) -> String {
switch allApps {
case false:
return "I further authorize this app to send me notifications. Read more at https://walletconnect.com/notifications"
case true:
return "I further authorize this app to view and manage my notifications for ALL apps. Read more at https://walletconnect.com/notifications"
}
}
}

#if targetEnvironment(simulator)
extension NotifyClient {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,11 @@ public struct NotifyClientFactory {
let notifySubscriptionsChangedRequestSubscriber = NotifySubscriptionsChangedRequestSubscriber(keyserver: keyserverURL, networkingInteractor: networkInteractor, kms: kms, identityClient: identityClient, logger: logger, groupKeychainStorage: groupKeychainStorage, notifyStorage: notifyStorage, notifySubscriptionsBuilder: notifySubscriptionsBuilder)
let subscriptionWatcher = SubscriptionWatcher(notifyWatchSubscriptionsRequester: notifyWatchSubscriptionsRequester, logger: logger)

let identityService = NotifyIdentityService(keyserverURL: keyserverURL, identityClient: identityClient, logger: logger)

return NotifyClient(
logger: logger,
keyserverURL: keyserverURL,
kms: kms,
identityService: identityService,
identityClient: identityClient,
pushClient: pushClient,
notifyMessageSubscriber: notifyMessageSubscriber,
notifyStorage: notifyStorage,
Expand Down

This file was deleted.

0 comments on commit ebe4f86

Please sign in to comment.