Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add additional wallets to a client #383

Closed
wants to merge 10 commits into from
22 changes: 22 additions & 0 deletions Sources/XMTPiOS/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -602,4 +602,26 @@ public final class Client {
}
try await client.requestHistorySync()
}

public func addWallet(account: SigningKey) async throws {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After adding the wallet to their identity what benefits do they get/ how can the interact with the wallet?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would allow someone else to enter any one of the added wallet addresses and reach the same inbox.

And for an app that has access to any of the added wallets to create a new installation for that inbox.

guard let client = v3Client else {
throw ClientError.noV3Client("Error: No V3 client initialized")
}

do {
let signatureRequest = try await client.addWallet(existingWalletAddress: self.address, newWalletAddress: account.address)

let signedData = try await account.sign(message: signatureRequest.signatureText())

if let chainRPCUrl = account.chainRPCUrl {
try await signatureRequest.addScwSignature(signatureBytes: signedData.rawData, address: account.address, chainRpcUrl: chainRPCUrl)
nplasterer marked this conversation as resolved.
Show resolved Hide resolved
} else {
try await signatureRequest.addEcdsaSignature(signatureBytes: signedData.rawData)
}

try await client.registerIdentity(signatureRequest: signatureRequest)
} catch {
throw ClientError.creationError("Failed to sign the message: \(error.localizedDescription)")
}
}
}
4 changes: 4 additions & 0 deletions Sources/XMTPiOS/Messages/PrivateKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ enum PrivateKeyError: Error, CustomStringConvertible {
}

extension PrivateKey: SigningKey {
public var chainRPCUrl: String? {
nil
}

public var address: String {
walletAddress
}
Expand Down
3 changes: 3 additions & 0 deletions Sources/XMTPiOS/SigningKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import LibXMTP
public protocol SigningKey {
/// A wallet address for this key
var address: String { get }

/// Chain rpc url for the smart contract wallet
var chainRPCUrl: String? { get }
Copy link
Contributor Author

@nplasterer nplasterer Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@neekolas I think I need some knowledge sharing on how this chainRPC is supposed to be set. If it's okay for it to be on the signing key which is an interface implemented by the integrator.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was all done a while ago, and not by me, so my recollection is a little fuzzy on where and when we need to pass in the chainRPC.

But generally it's a thing that dapps will have (it's the URL you'd get from an Infura or Alchemy dashboard). It wouldn't be "key specific", so it's probably safe to make it a client create parameter and save it there. We'd use the same RPC url for all signing keys.

We need it at the time we are creating or verifying smart contract wallet signatures.


/// Sign the data and return a secp256k1 compact recoverable signature.
func sign(_ data: Data) async throws -> Signature
Expand Down
Loading