Skip to content

Commit

Permalink
Merge pull request #767 from WalletConnect/push-envelope-type-1-response
Browse files Browse the repository at this point in the history
[Push] envelope type 1 response
  • Loading branch information
llbartekll authored Apr 4, 2023
2 parents 8f8be84 + d18b514 commit c296bc7
Show file tree
Hide file tree
Showing 36 changed files with 262 additions and 124 deletions.
6 changes: 3 additions & 3 deletions Example/DApp/Sign/Accounts/AccountsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ final class AccountsViewController: UIViewController, UITableViewDataSource, UIT
let account = session.namespaces.values.first!.accounts.first!

Task(priority: .high){ try! await Push.dapp.request(account: account, topic: session.pairingTopic)}
Push.dapp.responsePublisher.sink { (id: RPCID, result: Result<PushSubscription, PushError>) in
Push.dapp.responsePublisher.sink { (id: RPCID, result: Result<PushSubscriptionResult, PushError>) in
switch result {
case .success(let subscription):
self.pushSubscription = subscription
case .success(let subscriptionResult):
self.pushSubscription = subscriptionResult.pushSubscription
case .failure(let error):
print(error)
}
Expand Down
4 changes: 3 additions & 1 deletion Example/IntegrationTests/Pairing/PairingTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ final class PairingTests: XCTestCase {
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
walletPairingClient = pairingClient
let echoClient = EchoClientFactory.create(projectId: "", clientId: "", echoHost: "echo.walletconnect.com", environment: .sandbox)
walletPushClient = WalletPushClientFactory.create(logger: pushLogger,
let keyserverURL = URL(string: "https://keys.walletconnect.com")!
walletPushClient = WalletPushClientFactory.create(keyserverURL: keyserverURL,
logger: pushLogger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
groupKeychainStorage: KeychainStorageMock(),
Expand Down
39 changes: 24 additions & 15 deletions Example/IntegrationTests/Push/PushTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import WalletConnectNetworking
import WalletConnectEcho
@testable import WalletConnectPush
@testable import WalletConnectPairing
import WalletConnectIdentity
import WalletConnectSigner

final class PushTests: XCTestCase {

Expand Down Expand Up @@ -70,7 +72,9 @@ final class PushTests: XCTestCase {
let pushLogger = ConsoleLogger(suffix: prefix + " [Push]", loggingLevel: .debug)
walletPairingClient = pairingClient
let echoClient = EchoClientFactory.create(projectId: "", clientId: "", echoHost: "echo.walletconnect.com", environment: .sandbox)
walletPushClient = WalletPushClientFactory.create(logger: pushLogger,
let keyserverURL = URL(string: "https://keys.walletconnect.com")!
walletPushClient = WalletPushClientFactory.create(keyserverURL: keyserverURL,
logger: pushLogger,
keyValueStorage: keyValueStorage,
keychainStorage: keychain,
groupKeychainStorage: KeychainStorageMock(),
Expand Down Expand Up @@ -106,8 +110,7 @@ final class PushTests: XCTestCase {
try! await dappPushClient.request(account: Account.stub(), topic: uri.topic)

walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in

Task(priority: .high) { try! await walletPushClient.approve(id: id) }
Task(priority: .high) { try! await walletPushClient.approve(id: id, onSign: sign) }
}.store(in: &publishers)

dappPushClient.responsePublisher.sink { (_, result) in
Expand Down Expand Up @@ -153,16 +156,16 @@ final class PushTests: XCTestCase {
try! await dappPushClient.request(account: Account.stub(), topic: uri.topic)

walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in
Task(priority: .high) { try! await walletPushClient.approve(id: id) }
Task(priority: .high) { try! await walletPushClient.approve(id: id, onSign: sign) }
}.store(in: &publishers)

dappPushClient.responsePublisher.sink { [unowned self] (_, result) in
guard case .success(let subscription) = result else {
guard case .success(let result) = result else {
XCTFail()
return
}
pushSubscription = subscription
Task(priority: .userInitiated) { try! await dappPushClient.notify(topic: subscription.topic, message: pushMessage) }
pushSubscription = result.pushSubscription
Task(priority: .userInitiated) { try! await dappPushClient.notify(topic: result.pushSubscription.topic, message: pushMessage) }
}.store(in: &publishers)

walletPushClient.pushMessagePublisher.sink { [unowned self] receivedPushMessageRecord in
Expand All @@ -185,16 +188,16 @@ final class PushTests: XCTestCase {
var subscriptionTopic: String!

walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in
Task(priority: .high) { try! await walletPushClient.approve(id: id) }
Task(priority: .high) { try! await walletPushClient.approve(id: id, onSign: sign) }
}.store(in: &publishers)

dappPushClient.responsePublisher.sink { [unowned self] (_, result) in
guard case .success(let subscription) = result else {
guard case .success(let result) = result else {
XCTFail()
return
}
subscriptionTopic = subscription.topic
Task(priority: .userInitiated) { try! await walletPushClient.deleteSubscription(topic: subscription.topic)}
subscriptionTopic = result.pushSubscription.topic
Task(priority: .userInitiated) { try! await walletPushClient.deleteSubscription(topic: result.pushSubscription.topic)}
}.store(in: &publishers)

dappPushClient.deleteSubscriptionPublisher.sink { topic in
Expand All @@ -212,16 +215,16 @@ final class PushTests: XCTestCase {
var subscriptionTopic: String!

walletPushClient.requestPublisher.sink { [unowned self] (id, _, _) in
Task(priority: .high) { try! await walletPushClient.approve(id: id) }
Task(priority: .high) { try! await walletPushClient.approve(id: id, onSign: sign) }
}.store(in: &publishers)

dappPushClient.responsePublisher.sink { [unowned self] (_, result) in
guard case .success(let subscription) = result else {
guard case .success(let result) = result else {
XCTFail()
return
}
subscriptionTopic = subscription.topic
Task(priority: .userInitiated) { try! await dappPushClient.delete(topic: subscription.topic)}
subscriptionTopic = result.pushSubscription.topic
Task(priority: .userInitiated) { try! await dappPushClient.delete(topic: result.pushSubscription.topic)}
}.store(in: &publishers)

walletPushClient.deleteSubscriptionPublisher.sink { topic in
Expand All @@ -230,4 +233,10 @@ final class PushTests: XCTestCase {
}.store(in: &publishers)
wait(for: [expectation], timeout: InputConfig.defaultTimeout)
}

private func sign(_ message: String) -> SigningResult {
let privateKey = Data(hex: "305c6cde3846927892cd32762f6120539f3ec74c9e3a16b9b798b1e85351ae2a")
let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create(projectId: InputConfig.projectId)
return .signed(try! signer.sign(message: message, privateKey: privateKey, type: .eip191))
}
}
2 changes: 1 addition & 1 deletion Example/IntegrationTests/Stubs/Account.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import WalletConnectUtils

extension Account {
static func stub() -> Account {
return Account(chainIdentifier: "eip155:1", address: "0x724d0D2DaD3fbB0C168f947B87Fa5DBe36F1A8bf")!
return Account(chainIdentifier: "eip155:1", address: "0x15bca56b6e2728aec2532df9d436bd1600e86688")!
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,17 @@ import WalletConnectPush

final class PushRequestInteractor {
func approve(pushRequest: PushRequest) async throws {
try await Push.wallet.approve(id: pushRequest.id)
try await Push.wallet.approve(id: pushRequest.id, onSign: onSing(_:))
}

func reject(pushRequest: PushRequest) async throws {
try await Push.wallet.reject(id: pushRequest.id)
}

func onSing(_ message: String) async -> SigningResult {
let privateKey = Data(hex: "e56da0e170b5e09a8bb8f1b693392c7d56c3739a9c75740fbc558a2877868540")
let signer = MessageSignerFactory(signerFactory: DefaultSignerFactory()).create()
let signature = try! signer.sign(message: message, privateKey: privateKey, type: .eip191)
return .signed(signature)
}
}
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ let package = Package(
path: "Sources/Web3Wallet"),
.target(
name: "WalletConnectPush",
dependencies: ["WalletConnectPairing", "WalletConnectEcho", "WalletConnectNetworking"],
dependencies: ["WalletConnectPairing", "WalletConnectEcho", "WalletConnectNetworking", "WalletConnectIdentity"],
path: "Sources/WalletConnectPush"),
.target(
name: "WalletConnectEcho",
Expand Down
6 changes: 3 additions & 3 deletions Sources/Chat/ProtocolServices/Common/MessagingService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ private extension MessagingService {
logger.debug("Received Receipt response")

guard
let (message, _) = try? MessagePayload.decode(from: payload.request),
let (receipt, _) = try? ReceiptPayload.decode(from: payload.response)
let (message, _) = try? MessagePayload.decodeAndVerify(from: payload.request),
let (receipt, _) = try? ReceiptPayload.decodeAndVerify(from: payload.response)
else { fatalError() /* TODO: Handle error */ }

let newMessage = Message(
Expand All @@ -79,7 +79,7 @@ private extension MessagingService {

logger.debug("Received Message Request")

guard let (message, messageClaims) = try? MessagePayload.decode(from: payload.request)
guard let (message, messageClaims) = try? MessagePayload.decodeAndVerify(from: payload.request)
else { fatalError() /* TODO: Handle error */ }

Task(priority: .high) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ private extension InvitationHandlingService {
.sink { [unowned self] (payload: RequestSubscriptionPayload<InvitePayload.Wrapper>) in
logger.debug("Did receive an invite")

guard let (invite, claims) = try? InvitePayload.decode(from: payload.request)
guard let (invite, claims) = try? InvitePayload.decodeAndVerify(from: payload.request)
else { fatalError() /* TODO: Handle error */ }

Task(priority: .high) {
Expand Down
4 changes: 2 additions & 2 deletions Sources/Chat/ProtocolServices/Inviter/InviteService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ private extension InviteService {
logger.debug("Invite has been accepted")

guard
let (invite, _) = try? InvitePayload.decode(from: payload.request),
let (accept, _) = try? AcceptPayload.decode(from: payload.response)
let (invite, _) = try? InvitePayload.decodeAndVerify(from: payload.request),
let (accept, _) = try? AcceptPayload.decodeAndVerify(from: payload.response)
else { fatalError() /* TODO: Handle error */ }

Task(priority: .high) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/WalletConnectJWT/JWTDecodable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public protocol JWTClaimsCodable {

extension JWTClaimsCodable {

public static func decode(from wrapper: Wrapper) throws -> (Self, Claims) {
public static func decodeAndVerify(from wrapper: Wrapper) throws -> (Self, Claims) {
let jwt = try JWT<Claims>(string: wrapper.jwtString)

let publicKey = try DIDKey(did: jwt.claims.iss)
Expand Down
13 changes: 7 additions & 6 deletions Sources/WalletConnectKMS/Serialiser/Serializer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ public class Serializer: Serializing {
/// - topic: Topic that is associated with a symetric key for decrypting particular codable object
/// - encodedEnvelope: Envelope to deserialize and decrypt
/// - Returns: Deserialized object
public func deserialize<T: Codable>(topic: String, encodedEnvelope: String) throws -> T {
public func deserialize<T: Codable>(topic: String, encodedEnvelope: String) throws -> (T, derivedTopic: String?) {
let envelope = try Envelope(encodedEnvelope)
switch envelope.type {
case .type0:
return try handleType0Envelope(topic, envelope)
let deserialisedType: T = try handleType0Envelope(topic, envelope)
return (deserialisedType, nil)
case .type1(let peerPubKey):
return try handleType1Envelope(topic, peerPubKey: peerPubKey, sealbox: envelope.sealbox)
}
Expand All @@ -58,15 +59,15 @@ public class Serializer: Serializing {
}
}

private func handleType1Envelope<T: Codable>(_ topic: String, peerPubKey: Data, sealbox: Data) throws -> T {
private func handleType1Envelope<T: Codable>(_ topic: String, peerPubKey: Data, sealbox: Data) throws -> (T, String) {
guard let selfPubKey = kms.getPublicKey(for: topic)
else { throw Errors.publicKeyForTopicNotFound }

let agreementKeys = try kms.performKeyAgreement(selfPublicKey: selfPubKey, peerPublicKey: peerPubKey.toHexString())
let decodedType: T = try decode(sealbox: sealbox, symmetricKey: agreementKeys.sharedKey.rawRepresentation)
let newTopic = agreementKeys.derivedTopic()
try kms.setAgreementSecret(agreementKeys, topic: newTopic)
return decodedType
let derivedTopic = agreementKeys.derivedTopic()
try kms.setAgreementSecret(agreementKeys, topic: derivedTopic)
return (decodedType, derivedTopic)
}

private func decode<T: Codable>(sealbox: Data, symmetricKey: Data) throws -> T {
Expand Down
6 changes: 4 additions & 2 deletions Sources/WalletConnectKMS/Serialiser/Serializing.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import Foundation

public protocol Serializing {
func serialize(topic: String, encodable: Encodable, envelopeType: Envelope.EnvelopeType) throws -> String
func deserialize<T: Codable>(topic: String, encodedEnvelope: String) throws -> T
/// - derivedTopic: topic derived from symmetric key as a result of key exchange if peers has sent envelope(type1) prefixed with it's public key
func deserialize<T: Codable>(topic: String, encodedEnvelope: String) throws -> (T, derivedTopic: String?)
}

public extension Serializing {
func tryDeserialize<T: Codable>(topic: String, encodedEnvelope: String) -> T? {
/// - derivedTopic: topic derived from symmetric key as a result of key exchange if peers has sent envelope(type1) prefixed with it's public key
func tryDeserialize<T: Codable>(topic: String, encodedEnvelope: String) -> (T, derivedTopic: String?)? {
return try? deserialize(topic: topic, encodedEnvelope: encodedEnvelope)
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/WalletConnectNetworking/NetworkInteracting.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Combine

public protocol NetworkInteracting {
var socketConnectionStatusPublisher: AnyPublisher<SocketConnectionStatus, Never> { get }
var requestPublisher: AnyPublisher<(topic: String, request: RPCRequest, publishedAt: Date), Never> { get }
var requestPublisher: AnyPublisher<(topic: String, request: RPCRequest, publishedAt: Date, derivedTopic: String?), Never> { get }
func subscribe(topic: String) async throws
func unsubscribe(topic: String)
func batchSubscribe(topics: [String]) async throws
Expand Down
Loading

0 comments on commit c296bc7

Please sign in to comment.