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

Smart Contract Wallets #403

Merged
merged 38 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ede8122
update package
nplasterer Sep 13, 2024
70c3a41
Merge branch 'main' of https://github.com/xmtp/xmtp-ios
nplasterer Sep 13, 2024
c72c33c
Merge branch 'main' of https://github.com/xmtp/xmtp-ios
nplasterer Sep 20, 2024
2f9cca8
add chain id and SCW check
nplasterer Sep 20, 2024
4e43786
add implementation
nplasterer Sep 20, 2024
ede8c29
fix a little formatting
nplasterer Sep 21, 2024
fd8ddc1
change defaults
nplasterer Sep 21, 2024
bc9fb62
Merge branch 'main' of https://github.com/xmtp/xmtp-ios
nplasterer Sep 22, 2024
65a4aaa
make a test release pod
nplasterer Sep 24, 2024
a366503
bump the latest libxmtp
nplasterer Sep 24, 2024
a46302b
fix up all the async tests
nplasterer Sep 24, 2024
16e2e6d
add installation timestamps and async members
nplasterer Sep 26, 2024
35f8053
Merge branch 'main' of https://github.com/xmtp/xmtp-ios into np/smart…
nplasterer Sep 26, 2024
f02d489
fix up the tests and bump the pod
nplasterer Sep 26, 2024
0e8ab5b
Merge branch 'np/stream-groups-logging' of https://github.com/xmtp/xm…
nplasterer Sep 26, 2024
e246103
bump to the next version
nplasterer Sep 26, 2024
f19b9b7
Merge branch 'main' of https://github.com/xmtp/xmtp-ios into np/smart…
nplasterer Sep 26, 2024
ef8dea9
bad merge
nplasterer Sep 26, 2024
03d4215
Merge branch 'main' of https://github.com/xmtp/xmtp-ios into np/smart…
nplasterer Oct 2, 2024
67a88fc
update the package
nplasterer Oct 2, 2024
929ac84
fix up bad merge
nplasterer Oct 2, 2024
a2d472a
Merge branch 'main' of https://github.com/xmtp/xmtp-ios into np/smart…
nplasterer Oct 9, 2024
63b79e1
make block number optional
nplasterer Oct 9, 2024
402ee51
add a test to reproduce the scw error
nplasterer Oct 9, 2024
d1f509d
update to latest libxmtp
nplasterer Oct 11, 2024
abe6af8
update the signers
nplasterer Oct 18, 2024
2cd20ce
update to the latest libxmtp functions
nplasterer Oct 18, 2024
2812b8a
fix the linter
nplasterer Oct 18, 2024
b03101f
get on a working version
nplasterer Oct 19, 2024
263bf64
check the chain id
nplasterer Oct 19, 2024
14b0cff
chain id is optional
nplasterer Oct 19, 2024
b986370
fix the lint issue
nplasterer Oct 20, 2024
87b8b42
tag
nplasterer Oct 20, 2024
4f36f8c
remove chain id from inbox id creation
nplasterer Oct 23, 2024
e704cea
update the SCW functionality and message listing
nplasterer Oct 23, 2024
39e52ef
small tweak to message listing
nplasterer Oct 23, 2024
b1678a9
get closer
nplasterer Oct 23, 2024
b169c71
small test clean up
nplasterer Oct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion Sources/XMTPiOS/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,14 @@ public final class Client {
if let signingKey = signingKey {
do {
let signedData = try await signingKey.sign(message: signatureRequest.signatureText())
try await signatureRequest.addEcdsaSignature(signatureBytes: signedData.rawData)
if signingKey.isSmartContractWallet {
guard isValidAccountID(signingKey.address) else {
throw ClientError.creationError("Account address must conform to CAIP format")
}
try await signatureRequest.addScwSignature(signatureBytes: signedData.rawData, address: signingKey.address, chainId: signingKey.chainId, blockNumber: signingKey.blockNumber)
} else {
try await signatureRequest.addEcdsaSignature(signatureBytes: signedData.rawData)
}
try await v3Client.registerIdentity(signatureRequest: signatureRequest)
} catch {
throw ClientError.creationError("Failed to sign the message: \(error.localizedDescription)")
Expand Down Expand Up @@ -696,4 +703,22 @@ public final class Client {
}
return InboxState(ffiInboxState: try await client.inboxState(refreshFromNetwork: refreshFromNetwork))
}

// See for more details https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md
public func isValidAccountID(_ accountAddress: String) -> Bool {
nplasterer marked this conversation as resolved.
Show resolved Hide resolved
// Define the regular expressions for chain_id and account_address
let chainIDPattern = "[-a-z0-9]{3,8}:[-_a-zA-Z0-9]{1,32}"
let accountAddressPattern = "[-.%a-zA-Z0-9]{1,128}"

// Combine them to match the entire account_id format
let accountIDPattern = "^\(chainIDPattern):\(accountAddressPattern)$"

let regex = try? NSRegularExpression(pattern: accountIDPattern)

if let match = regex?.firstMatch(in: accountAddress, options: [], range: NSRange(location: 0, length: accountAddress.utf16.count)) {
return match.range.location != NSNotFound
} else {
return false
}
}
}
21 changes: 21 additions & 0 deletions Sources/XMTPiOS/SigningKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ import LibXMTP
public protocol SigningKey {
/// A wallet address for this key
var address: String { get }

/// If this signing key is a smart contract wallet
var isSmartContractWallet: Bool { get }

/// The name of the chainId for example "eip155:1"
var chainId: UInt64 { get }

/// The blockNumber of the chain for example "1"
var blockNumber: UInt64 { get }

/// Sign the data and return a secp256k1 compact recoverable signature.
func sign(_ data: Data) async throws -> Signature
Expand All @@ -29,6 +38,18 @@ public protocol SigningKey {
}

extension SigningKey {
public var isSmartContractWallet: Bool {
return false
}

public var chainId: UInt64 {
return "eip155:1"
}

public var blockNumber: UInt64 {
return "eip155:1"
}
nplasterer marked this conversation as resolved.
Show resolved Hide resolved

func createIdentity(_ identity: PrivateKey, preCreateIdentityCallback: PreEventCallback? = nil) async throws -> AuthorizedIdentity {
var slimKey = PublicKey()
slimKey.timestamp = UInt64(Date().millisecondsSinceEpoch)
Expand Down
Loading