Skip to content

Commit

Permalink
App to did:web
Browse files Browse the repository at this point in the history
  • Loading branch information
flypaper0 committed Sep 11, 2023
1 parent d86ca1f commit b76b0bf
Show file tree
Hide file tree
Showing 15 changed files with 80 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ actor NotifyConfigProvider {

private var cache = [String: Set<NotificationType>]()

func getSubscriptionScope(dappUrl: String) async throws -> Set<NotificationType> {
if let availableScope = cache[dappUrl] {
func getSubscriptionScope(appDomain: String) async throws -> Set<NotificationType> {
if let availableScope = cache[appDomain] {
return availableScope
}
guard let notifyConfigUrl = URL(string: "https://\(dappUrl)/.well-known/wc-notify-config.json") else { throw Errors.invalidUrl }
guard let notifyConfigUrl = URL(string: "https://\(appDomain)/.well-known/wc-notify-config.json") else { throw Errors.invalidUrl }
let (data, _) = try await URLSession.shared.data(from: notifyConfigUrl)
let config = try JSONDecoder().decode(NotificationConfig.self, from: data)
let availableScope = Set(config.types)
cache[dappUrl] = availableScope
cache[appDomain] = availableScope
return availableScope
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class NotifySubscriptionsBuilder {
}

private func buildScope(selectedScope: [String], appDomain: String) async throws -> [String: ScopeValue] {
let availableScope = try await notifyConfigProvider.getSubscriptionScope(dappUrl: appDomain)
let availableScope = try await notifyConfigProvider.getSubscriptionScope(appDomain: appDomain)
return availableScope.reduce(into: [:]) {
$0[$1.name] = ScopeValue(description: $1.description, enabled: selectedScope.contains($1.name))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class DeleteNotifySubscriptionRequester {
let wrapper = try createJWTWrapper(
dappPubKey: DIDKey(rawData: dappAuthenticationKey),
reason: NotifyDeleteParams.userDisconnected.message,
app: subscription.metadata.url,
app: DIDWeb(host: subscription.metadata.url),
account: subscription.account
)

Expand All @@ -66,7 +66,7 @@ class DeleteNotifySubscriptionRequester {

private extension DeleteNotifySubscriptionRequester {

func createJWTWrapper(dappPubKey: DIDKey, reason: String, app: String, account: Account) throws -> NotifyDeletePayload.Wrapper {
func createJWTWrapper(dappPubKey: DIDKey, reason: String, app: DIDWeb, account: Account) throws -> NotifyDeletePayload.Wrapper {
let jwtPayload = NotifyDeletePayload(keyserver: keyserver, dappPubKey: dappPubKey, reason: reason, app: app)
return try identityClient.signAndCreateWrapper(
payload: jwtPayload,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,19 @@ class NotifyUpdateRequester: NotifyUpdateRequesting {
let request = try createJWTRequest(
dappPubKey: DIDKey(rawData: dappAuthenticationKey),
subscriptionAccount: subscription.account,
dappUrl: subscription.metadata.url, scope: scope
appDomain: subscription.metadata.url, scope: scope
)

let protocolMethod = NotifyUpdateProtocolMethod()

try await networkingInteractor.request(request, topic: topic, protocolMethod: protocolMethod)
}

private func createJWTRequest(dappPubKey: DIDKey, subscriptionAccount: Account, dappUrl: String, scope: Set<String>) throws -> RPCRequest {
private func createJWTRequest(dappPubKey: DIDKey, subscriptionAccount: Account, appDomain: String, scope: Set<String>) throws -> RPCRequest {
let protocolMethod = NotifyUpdateProtocolMethod().method
let scopeClaim = scope.joined(separator: " ")
let jwtPayload = NotifyUpdatePayload(dappPubKey: dappPubKey, keyserver: keyserverURL, subscriptionAccount: subscriptionAccount, dappUrl: dappUrl, scope: scopeClaim)
let app = DIDWeb(host: appDomain)
let jwtPayload = NotifyUpdatePayload(dappPubKey: dappPubKey, keyserver: keyserverURL, subscriptionAccount: subscriptionAccount, app: app, scope: scopeClaim)
let wrapper = try identityClient.signAndCreateWrapper(
payload: jwtPayload,
account: subscriptionAccount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ private extension NotifyUpdateResponseSubscriber {
let (requestPayload, requestClaims) = try NotifyUpdatePayload.decodeAndVerify(from: payload.request)
let (_, _) = try NotifyUpdateResponsePayload.decodeAndVerify(from: payload.response)

let scope = try await buildScope(selected: requestPayload.scope, dappUrl: requestPayload.dappUrl)
let scope = try await buildScope(selected: requestPayload.scope, appDomain: requestPayload.app.host)

guard let oldSubscription = notifyStorage.getSubscription(topic: subscriptionTopic) else {
logger.debug("NotifyUpdateResponseSubscriber Subscription does not exist")
Expand All @@ -56,9 +56,9 @@ private extension NotifyUpdateResponseSubscriber {
}
}

func buildScope(selected: String, dappUrl: String) async throws -> [String: ScopeValue] {
func buildScope(selected: String, appDomain: String) async throws -> [String: ScopeValue] {
let selectedScope = selected.components(separatedBy: " ")
let availableScope = try await nofityConfigProvider.getSubscriptionScope(dappUrl: dappUrl)
let availableScope = try await nofityConfigProvider.getSubscriptionScope(appDomain: appDomain)
return availableScope.reduce(into: [:]) {
$0[$1.name] = ScopeValue(description: $1.description, enabled: selectedScope.contains($1.name))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class NotifySubscribeRequester {
let subscriptionAuthWrapper = try await createJWTWrapper(
dappPubKey: DIDKey(did: peerPublicKey.did),
subscriptionAccount: account,
dappUrl: appDomain
appDomain: appDomain
)
let request = RPCRequest(method: protocolMethod.method, params: subscriptionAuthWrapper)

Expand All @@ -79,10 +79,11 @@ class NotifySubscribeRequester {
return keys
}

private func createJWTWrapper(dappPubKey: DIDKey, subscriptionAccount: Account, dappUrl: String) async throws -> NotifySubscriptionPayload.Wrapper {
let types = try await notifyConfigProvider.getSubscriptionScope(dappUrl: dappUrl)
private func createJWTWrapper(dappPubKey: DIDKey, subscriptionAccount: Account, appDomain: String) async throws -> NotifySubscriptionPayload.Wrapper {
let types = try await notifyConfigProvider.getSubscriptionScope(appDomain: appDomain)
let scope = types.map{$0.name}.joined(separator: " ")
let jwtPayload = NotifySubscriptionPayload(dappPubKey: dappPubKey, keyserver: keyserverURL, subscriptionAccount: subscriptionAccount, dappUrl: dappUrl, scope: scope)
let app = DIDWeb(host: appDomain)
let jwtPayload = NotifySubscriptionPayload(dappPubKey: dappPubKey, keyserver: keyserverURL, subscriptionAccount: subscriptionAccount, app: app, scope: scope)
return try identityClient.signAndCreateWrapper(
payload: jwtPayload,
account: subscriptionAccount
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class NotifySubscribeResponseSubscriber {
try groupKeychainStorage.add(agreementKeysP, forKey: notifySubscriptionTopic)
account = try Account(DIDPKHString: claims.sub)
metadata = try dappsMetadataStore.get(key: payload.topic)
let availableTypes = try await notifyConfigProvider.getSubscriptionScope(dappUrl: metadata!.url)
let availableTypes = try await notifyConfigProvider.getSubscriptionScope(appDomain: metadata!.url)
subscribedTypes = availableTypes.filter{subscribedScope.contains($0.name)}
logger.debug("NotifySubscribeResponseSubscriber: subscribing notify subscription topic: \(notifySubscriptionTopic!)")
try await networkingInteractor.subscribe(topic: notifySubscriptionTopic)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ struct NotifyDeletePayload: JWTClaimsCodable {
let keyserver: URL
let dappPubKey: DIDKey
let reason: String
let app: String
let app: DIDWeb

init(
keyserver: URL,
dappPubKey: DIDKey,
reason: String,
app: String
app: DIDWeb
) {
self.keyserver = keyserver
self.dappPubKey = dappPubKey
Expand All @@ -59,7 +59,7 @@ struct NotifyDeletePayload: JWTClaimsCodable {
self.keyserver = try claims.ksu.asURL()
self.dappPubKey = try DIDKey(did: claims.aud)
self.reason = claims.sub
self.app = claims.app
self.app = try DIDWeb(did: claims.app)
}

func encode(iss: String) throws -> Claims {
Expand All @@ -71,7 +71,7 @@ struct NotifyDeletePayload: JWTClaimsCodable {
iss: iss,
aud: dappPubKey.did(variant: .ED25519),
sub: reason,
app: app
app: app.did
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ struct NotifyDeleteResponsePayload: JWTClaimsCodable {

let selfPubKey: DIDKey
let subscriptionHash: String
let app: String
let app: DIDWeb

init(claims: Claims) throws {
self.selfPubKey = try DIDKey(did: claims.aud)
self.subscriptionHash = claims.sub
self.app = claims.app
self.app = try DIDWeb(did: claims.app)
}

func encode(iss: String) throws -> Claims {
Expand All @@ -54,7 +54,7 @@ struct NotifyDeleteResponsePayload: JWTClaimsCodable {
iss: iss,
aud: selfPubKey.did(variant: .ED25519),
sub: subscriptionHash,
app: app
app: app.did
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ struct NotifyMessagePayload: JWTClaimsCodable {
let dappAuthenticationKey: DIDKey
let account: Account
let subscriptionId: String
let app: String
let app: DIDWeb
let message: NotifyMessage

init(claims: Claims) throws {
self.dappAuthenticationKey = try DIDKey(did: claims.iss)
self.account = try DIDPKH(did: claims.aud).account
self.subscriptionId = claims.sub
self.app = claims.app
self.app = try DIDWeb(did: claims.app)
self.message = claims.msg
}

Expand All @@ -60,9 +60,9 @@ struct NotifyMessagePayload: JWTClaimsCodable {
iss: dappAuthenticationKey.multibase(variant: .ED25519),
aud: account.did,
sub: subscriptionId,
app: app,
app: app.did,
msg: message
)
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ struct NotifyMessageReceiptPayload: JWTClaimsCodable {
let keyserver: URL
let dappPubKey: DIDKey
let messageHash: String
let app: String
let app: DIDWeb

init(
keyserver: URL,
dappPubKey: DIDKey,
messageHash: String,
app: String
app: DIDWeb
) {
self.keyserver = keyserver
self.dappPubKey = dappPubKey
Expand All @@ -59,7 +59,7 @@ struct NotifyMessageReceiptPayload: JWTClaimsCodable {
self.keyserver = try claims.ksu.asURL()
self.dappPubKey = try DIDKey(did: claims.aud)
self.messageHash = claims.sub
self.app = claims.app
self.app = try DIDWeb(did: claims.app)
}

func encode(iss: String) throws -> Claims {
Expand All @@ -71,7 +71,7 @@ struct NotifyMessageReceiptPayload: JWTClaimsCodable {
iss: iss,
aud: dappPubKey.did(variant: .ED25519),
sub: messageHash,
app: app
app: app.did
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ struct NotifySubscriptionPayload: JWTClaimsCodable {
let dappPubKey: DIDKey
let keyserver: URL
let subscriptionAccount: Account
let dappUrl: String
let app: DIDWeb
let scope: String

init(dappPubKey: DIDKey, keyserver: URL, subscriptionAccount: Account, dappUrl: String, scope: String) {
init(dappPubKey: DIDKey, keyserver: URL, subscriptionAccount: Account, app: DIDWeb, scope: String) {
self.dappPubKey = dappPubKey
self.keyserver = keyserver
self.subscriptionAccount = subscriptionAccount
self.dappUrl = dappUrl
self.app = app
self.scope = scope
}

init(claims: Claims) throws {
self.dappPubKey = try DIDKey(did: claims.aud)
self.keyserver = try claims.ksu.asURL()
self.subscriptionAccount = try Account(DIDPKHString: claims.sub)
self.dappUrl = claims.app
self.app = try DIDWeb(did: claims.app)
self.scope = claims.scp
}

Expand All @@ -72,7 +72,7 @@ struct NotifySubscriptionPayload: JWTClaimsCodable {
aud: dappPubKey.did(variant: .ED25519),
sub: subscriptionAccount.did,
scp: scope,
app: dappUrl
app: app.did
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,22 @@ struct NotifyUpdatePayload: JWTClaimsCodable {
let dappPubKey: DIDKey
let keyserver: URL
let subscriptionAccount: Account
let dappUrl: String
let app: DIDWeb
let scope: String

init(dappPubKey: DIDKey, keyserver: URL, subscriptionAccount: Account, dappUrl: String, scope: String) {
init(dappPubKey: DIDKey, keyserver: URL, subscriptionAccount: Account, app: DIDWeb, scope: String) {
self.dappPubKey = dappPubKey
self.keyserver = keyserver
self.subscriptionAccount = subscriptionAccount
self.dappUrl = dappUrl
self.app = app
self.scope = scope
}

init(claims: Claims) throws {
self.dappPubKey = try DIDKey(did: claims.aud)
self.keyserver = try claims.ksu.asURL()
self.subscriptionAccount = try Account(DIDPKHString: claims.sub)
self.dappUrl = claims.app
self.app = try DIDWeb(did: claims.app)
self.scope = claims.scp
}

Expand All @@ -72,7 +72,7 @@ struct NotifyUpdatePayload: JWTClaimsCodable {
aud: dappPubKey.did(variant: .ED25519),
sub: subscriptionAccount.did,
scp: scope,
app: dappUrl
app: app.did
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ struct NotifyUpdateResponsePayload: JWTClaimsCodable {

let selfPubKey: DIDKey
let subscriptionHash: String
let app: String
let app: DIDWeb

init(claims: Claims) throws {
self.selfPubKey = try DIDKey(did: claims.aud)
self.subscriptionHash = claims.sub
self.app = claims.app
self.app = try DIDWeb(did: claims.app)
}

func encode(iss: String) throws -> Claims {
Expand All @@ -54,7 +54,7 @@ struct NotifyUpdateResponsePayload: JWTClaimsCodable {
iss: iss,
aud: selfPubKey.did(variant: .ED25519),
sub: subscriptionHash,
app: app
app: app.did
)
}
}
32 changes: 32 additions & 0 deletions Sources/WalletConnectUtils/DID/DIDWeb.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Foundation

public struct DIDWeb {

public let host: String

public init(url: URL) throws {
guard let host = url.host else { throw Errors.invalidUrl }
self.host = host
}

public init(did: String) throws {
guard let host = did.components(separatedBy: ":").last else { throw Errors.invalidDid }
self.host = host
}

public init(host: String) {
self.host = host
}

public var did: String {
return "did:web:\(host)"
}
}

extension DIDWeb {

enum Errors: Error {
case invalidUrl
case invalidDid
}
}

0 comments on commit b76b0bf

Please sign in to comment.