diff --git a/.github/workflows/deploy_to_cocoapods.yml b/.github/workflows/deploy_to_cocoapods.yml index e7b958bf..c15103c4 100644 --- a/.github/workflows/deploy_to_cocoapods.yml +++ b/.github/workflows/deploy_to_cocoapods.yml @@ -7,7 +7,7 @@ on: jobs: build: - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v1 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e05cbaa1..75fd495b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -32,7 +32,7 @@ jobs: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - runs-on: macos-12 + runs-on: macos-13 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 0ffd8a37..77f34eb1 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -8,11 +8,11 @@ on: jobs: build: name: Run swiftlint - runs-on: macos-12 + runs-on: macos-13 steps: - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: latest-stable + xcode-version: '14' - uses: actions/checkout@v3 - run: swiftlint Sources/ XMTPiOSExample/XMTPiOSExample - run: pod lib lint --allow-warnings diff --git a/Package.resolved b/Package.resolved index 5a21bff4..005bb9de 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,39 +1,21 @@ { "pins" : [ - { - "identity" : "bigint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/attaswift/BigInt", - "state" : { - "revision" : "793a7fac0bfc318e85994bf6900652e827aef33e", - "version" : "5.4.1" - } - }, { "identity" : "connect-swift", "kind" : "remoteSourceControl", "location" : "https://github.com/bufbuild/connect-swift", "state" : { - "revision" : "1701d3d1b2c4c63fcccfd7094f86a88672fa5acb", - "version" : "0.12.0" - } - }, - { - "identity" : "generic-json-swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/iwill/generic-json-swift", - "state" : { - "revision" : "0a06575f4038b504e78ac330913d920f1630f510", - "version" : "2.0.2" + "revision" : "a8c984a1077f78e94e0884c5c11683a7f684f92c", + "version" : "1.0.0" } }, { - "identity" : "gzipswift", + "identity" : "cryptoswift", "kind" : "remoteSourceControl", - "location" : "https://github.com/1024jp/GzipSwift", + "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", "state" : { - "revision" : "7a7f17761c76a932662ab77028a4329f67d645a4", - "version" : "5.2.0" + "revision" : "678d442c6f7828def400a70ae15968aef67ef52d", + "version" : "1.8.3" } }, { @@ -41,17 +23,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/xmtp/libxmtp-swift.git", "state" : { - "revision" : "abd4f896f539e5bb090c85022177d775ad08dcb1", - "version" : "0.5.8-beta4" + "revision" : "f495d4feaab40a0a6a48c1d5a99585de8107f5d2", + "version" : "3.0.1" } }, { "identity" : "secp256k1.swift", "kind" : "remoteSourceControl", - "location" : "https://github.com/GigaBitcoin/secp256k1.swift.git", + "location" : "https://github.com/Boilertalk/secp256k1.swift.git", "state" : { - "revision" : "48fb20fce4ca3aad89180448a127d5bc16f0e44c", - "version" : "0.10.0" + "revision" : "cd187c632fb812fd93711a9f7e644adb7e5f97f0", + "version" : "0.1.7" } }, { @@ -68,8 +50,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-collections.git", "state" : { - "revision" : "3d2dc41a01f9e49d84f0a3925fb858bed64f702d", - "version" : "1.1.2" + "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7", + "version" : "1.1.4" } }, { @@ -77,53 +59,26 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-docc-plugin.git", "state" : { - "revision" : "26ac5758409154cc448d7ab82389c520fa8a8247", - "version" : "1.3.0" + "revision" : "85e4bb4e1cd62cec64a4b8e769dcefdf0c5b9d64", + "version" : "1.4.3" } }, { "identity" : "swift-docc-symbolkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-docc-symbolkit", + "location" : "https://github.com/swiftlang/swift-docc-symbolkit", "state" : { "revision" : "b45d1f2ed151d057b54504d653e0da5552844e34", "version" : "1.0.0" } }, - { - "identity" : "swift-http-types", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-http-types", - "state" : { - "revision" : "1ddbea1ee34354a6a2532c60f98501c35ae8edfa", - "version" : "1.2.0" - } - }, - { - "identity" : "swift-log", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-log.git", - "state" : { - "revision" : "9cb486020ebf03bfa5b5df985387a14a98744537", - "version" : "1.6.1" - } - }, { "identity" : "swift-nio", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio.git", "state" : { - "revision" : "fc79798d5a150d61361a27ce0c51169b889e23de", - "version" : "2.68.0" - } - }, - { - "identity" : "swift-nio-extras", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-extras.git", - "state" : { - "revision" : "05c36b57453d23ea63785d58a7dbc7b70ba1745e", - "version" : "1.23.0" + "revision" : "914081701062b11e3bb9e21accc379822621995e", + "version" : "2.76.1" } }, { @@ -131,8 +86,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-http2.git", "state" : { - "revision" : "a0224f3d20438635dd59c9fcc593520d80d131d0", - "version" : "1.33.0" + "revision" : "eaa71bb6ae082eee5a07407b1ad0cbd8f48f9dca", + "version" : "1.34.1" } }, { @@ -140,17 +95,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-ssl.git", "state" : { - "revision" : "2b09805797f21c380f7dc9bedaab3157c5508efb", - "version" : "2.27.0" - } - }, - { - "identity" : "swift-nio-transport-services", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-transport-services.git", - "state" : { - "revision" : "38ac8221dd20674682148d6451367f89c2652980", - "version" : "1.21.0" + "revision" : "c7e95421334b1068490b5d41314a50e70bab23d1", + "version" : "2.29.0" } }, { @@ -158,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { - "revision" : "d57a5aecf24a25b32ec4a74be2f5d0a995a47c4b", - "version" : "1.27.0" + "revision" : "ebc7251dd5b37f627c93698e4374084d98409633", + "version" : "1.28.2" } }, { @@ -167,26 +113,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-system.git", "state" : { - "revision" : "6a9e38e7bd22a3b8ba80bddf395623cf68f57807", - "version" : "1.3.1" - } - }, - { - "identity" : "web3.swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/argentlabs/web3.swift", - "state" : { - "revision" : "1e75f98a5738c470b23bbfffa9314e9f788df76b", - "version" : "1.6.1" - } - }, - { - "identity" : "websocket-kit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/vapor/websocket-kit.git", - "state" : { - "revision" : "4232d34efa49f633ba61afde365d3896fc7f8740", - "version" : "2.15.0" + "revision" : "c8a44d836fe7913603e246acab7c528c2e780168", + "version" : "1.4.0" } } ], diff --git a/Package.swift b/Package.swift index f1b2eafd..1ecb5bc9 100644 --- a/Package.swift +++ b/Package.swift @@ -7,7 +7,6 @@ let package = Package( name: "XMTPiOS", platforms: [.iOS(.v14), .macOS(.v11)], products: [ - // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "XMTPiOS", targets: ["XMTPiOS"] @@ -18,26 +17,20 @@ let package = Package( ), ], dependencies: [ - // Dependencies declare other packages that this package depends on. - // .package(url: /* package url */, from: "1.0.0"), - .package(url: "https://github.com/GigaBitcoin/secp256k1.swift.git", exact: "0.10.0"), - .package(url: "https://github.com/argentlabs/web3.swift", from: "1.1.0"), - .package(url: "https://github.com/1024jp/GzipSwift", from: "5.2.0"), - .package(url: "https://github.com/bufbuild/connect-swift", exact: "0.12.0"), - .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.0.0"), + .package(url: "https://github.com/tesseract-one/CSecp256k1.swift.git", from: "0.2.0"), + .package(url: "https://github.com/bufbuild/connect-swift", exact: "1.0.0"), + .package(url: "https://github.com/apple/swift-docc-plugin.git", from: "1.4.3"), .package(url: "https://github.com/xmtp/libxmtp-swift.git", exact: "3.0.3"), + .package(url: "https://github.com/krzyzanowskim/CryptoSwift.git", exact: "1.8.3") ], targets: [ - // Targets are the basic building blocks of a package. A target can define a module or a test suite. - // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "XMTPiOS", dependencies: [ - .product(name: "secp256k1", package: "secp256k1.swift"), - "web3.swift", - .product(name: "Gzip", package: "GzipSwift"), + .product(name: "CSecp256k1", package: "CSecp256k1.swift"), .product(name: "Connect", package: "connect-swift"), - .product(name: "LibXMTP", package: "libxmtp-swift") + .product(name: "LibXMTP", package: "libxmtp-swift"), + .product(name: "CryptoSwift", package: "CryptoSwift") ] ), .target( diff --git a/Sources/XMTPTestHelpers/TestHelpers.swift b/Sources/XMTPTestHelpers/TestHelpers.swift index d32a1462..f5feb8f3 100644 --- a/Sources/XMTPTestHelpers/TestHelpers.swift +++ b/Sources/XMTPTestHelpers/TestHelpers.swift @@ -1,6 +1,5 @@ #if canImport(XCTest) import Combine - import CryptoKit import XCTest @testable import XMTPiOS import LibXMTP diff --git a/Sources/XMTPiOS/Client.swift b/Sources/XMTPiOS/Client.swift index b545a4b7..963bbda0 100644 --- a/Sources/XMTPiOS/Client.swift +++ b/Sources/XMTPiOS/Client.swift @@ -1,6 +1,5 @@ import Foundation import LibXMTP -import web3 public typealias PreEventCallback = () async throws -> Void diff --git a/Sources/XMTPiOS/Codecs/ContentCodec.swift b/Sources/XMTPiOS/Codecs/ContentCodec.swift index e715a191..c4d94556 100644 --- a/Sources/XMTPiOS/Codecs/ContentCodec.swift +++ b/Sources/XMTPiOS/Codecs/ContentCodec.swift @@ -40,7 +40,11 @@ extension EncodedContent { copy.compression = .gzip } - copy.content = try compression.compress(content: content) + if let compressedContent = compression.compress(content: content) { + copy.content = compressedContent + } else { + throw CodecError.invalidContent + } return copy } @@ -54,15 +58,24 @@ extension EncodedContent { switch compression { case .gzip: - copy.content = try EncodedContentCompression.gzip.decompress(content: content) + if let decompressedContent = EncodedContentCompression.gzip.decompress(content: content) { + copy.content = decompressedContent + } else { + throw CodecError.invalidContent + } case .deflate: - copy.content = try EncodedContentCompression.deflate.decompress(content: content) + if let decompressedContent = EncodedContentCompression.deflate.decompress(content: content) { + copy.content = decompressedContent + } else { + throw CodecError.invalidContent + } default: return copy } return copy } + } public protocol ContentCodec: Hashable, Equatable { diff --git a/Sources/XMTPiOS/Codecs/RemoteAttachmentCodec.swift b/Sources/XMTPiOS/Codecs/RemoteAttachmentCodec.swift index 19fe5d95..3d58c2e0 100644 --- a/Sources/XMTPiOS/Codecs/RemoteAttachmentCodec.swift +++ b/Sources/XMTPiOS/Codecs/RemoteAttachmentCodec.swift @@ -1,13 +1,6 @@ -// -// RemoteAttachmentCodec.swift -// -// -// Created by Pat Nakajima on 2/19/23. -// - import CryptoKit +import CryptoSwift import Foundation -import web3 public let ContentTypeRemoteAttachment = ContentTypeID(authorityID: "xmtp.org", typeID: "remoteStaticAttachment", versionMajor: 1, versionMinor: 0) @@ -217,11 +210,7 @@ public struct RemoteAttachmentCodec: ContentCodec { throw RemoteAttachmentError.invalidParameters("missing \(name) parameter") } - guard let parameterData = parameterHex.web3.hexData else { - throw RemoteAttachmentError.invalidParameters("invalid \(name) value") - } - - return Data(parameterData) + return Data(parameterHex.hexToData) } public func shouldPush(content: RemoteAttachment) throws -> Bool { diff --git a/Sources/XMTPiOS/Crypto.swift b/Sources/XMTPiOS/Crypto.swift index 04fe4f82..05e0b87f 100644 --- a/Sources/XMTPiOS/Crypto.swift +++ b/Sources/XMTPiOS/Crypto.swift @@ -1,7 +1,3 @@ -// -// Crypto.swift -// - import CryptoKit import Foundation diff --git a/Sources/XMTPiOS/EncodedContentCompression.swift b/Sources/XMTPiOS/EncodedContentCompression.swift index 1cb45c0c..5203ee0b 100644 --- a/Sources/XMTPiOS/EncodedContentCompression.swift +++ b/Sources/XMTPiOS/EncodedContentCompression.swift @@ -1,60 +1,71 @@ -// -// EncodedContentCompression.swift -// -// -// Created by Pat Nakajima on 1/19/23. -// - +import Compression import Foundation -import Gzip -import zlib public enum EncodedContentCompression { - case deflate, gzip + case deflate + case gzip - func compress(content: Data) throws -> Data { + func compress(content: Data) -> Data? { switch self { case .deflate: - // 78 9C - Default Compression according to https://www.ietf.org/rfc/rfc1950.txt - let header = Data([0x78, 0x9C]) - - // Perform rfc1951 compression - let compressed = try (content as NSData).compressed(using: .zlib) as Data - - // Needed for rfc1950 compliance - let checksum = adler32(content) - - return header + compressed + checksum + return compressData(content, using: COMPRESSION_ZLIB) case .gzip: - return try content.gzipped() + return compressData(content, using: COMPRESSION_LZFSE) // For GZIP, switch to COMPRESSION_ZLIB if needed. } } - func decompress(content: Data) throws -> Data { + func decompress(content: Data) -> Data? { switch self { case .deflate: - // Swift uses https://www.ietf.org/rfc/rfc1951.txt while JS uses https://www.ietf.org/rfc/rfc1950.txt - // They're basically the same except the JS version has a two byte header that we can just get rid of - // and a four byte checksum at the end that seems to be ignored here. - let data = NSData(data: content[2...]) - let inflated = try data.decompressed(using: .zlib) - return inflated as Data + return decompressData(content, using: COMPRESSION_ZLIB) case .gzip: - return try content.gunzipped() + return decompressData(content, using: COMPRESSION_LZFSE) // For GZIP, switch to COMPRESSION_ZLIB if needed. } } - private func adler32(_ data: Data) -> Data { - let prime = UInt32(65521) - var s1 = UInt32(1 & 0xFFFF) - var s2 = UInt32((1 >> 16) & 0xFFFF) - data.forEach { - s1 += UInt32($0) - if s1 >= prime { s1 = s1 % prime } - s2 += s1 - if s2 >= prime { s2 = s2 % prime } + // Helper method to compress data using the Compression framework + private func compressData( + _ data: Data, using algorithm: compression_algorithm + ) -> Data? { + let destinationBuffer = UnsafeMutablePointer.allocate( + capacity: data.count + ) + defer { destinationBuffer.deallocate() } + + let compressedSize = data.withUnsafeBytes { sourceBuffer -> Int in + guard let sourcePointer = sourceBuffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else { + return 0 // Return 0 to indicate failure + } + return compression_encode_buffer( + destinationBuffer, data.count, + sourcePointer, data.count, nil, algorithm + ) } - var result = ((s2 << 16) | s1).bigEndian - return Data(bytes: &result, count: MemoryLayout.size) + + guard compressedSize > 0 else { return nil } + return Data(bytes: destinationBuffer, count: compressedSize) + } + + // Helper method to decompress data using the Compression framework + private func decompressData( + _ data: Data, using algorithm: compression_algorithm + ) -> Data? { + let destinationBuffer = UnsafeMutablePointer.allocate( + capacity: data.count * 4 // Allocate enough memory for decompressed data + ) + defer { destinationBuffer.deallocate() } + + let decompressedSize = data.withUnsafeBytes { sourceBuffer -> Int in + guard let sourcePointer = sourceBuffer.baseAddress?.assumingMemoryBound(to: UInt8.self) else { + return 0 // Return 0 to indicate failure + } + return compression_decode_buffer( + destinationBuffer, data.count * 4, + sourcePointer, data.count, nil, algorithm + ) + } + + guard decompressedSize > 0 else { return nil } + return Data(bytes: destinationBuffer, count: decompressedSize) } } diff --git a/Sources/XMTPiOS/Extensions/String.swift b/Sources/XMTPiOS/Extensions/String.swift index b6fc6d21..bfa1186e 100644 --- a/Sources/XMTPiOS/Extensions/String.swift +++ b/Sources/XMTPiOS/Extensions/String.swift @@ -1,16 +1,9 @@ -// -// String.swift -// -// -// Created by Naomi Plasterer on 7/1/24. -// - import Foundation - +import CryptoSwift extension String { public var hexToData: Data { - return Data(self.web3.bytesFromHex ?? []) + return Data(hex: self) } } diff --git a/Sources/XMTPiOS/KeyUtil.swift b/Sources/XMTPiOS/KeyUtil.swift index bd7048ff..ea28ff9a 100644 --- a/Sources/XMTPiOS/KeyUtil.swift +++ b/Sources/XMTPiOS/KeyUtil.swift @@ -1,12 +1,7 @@ -// -// web3.swift -// Copyright © 2022 Argent Labs Limited. All rights reserved. -// import Foundation -import Logging -import secp256k1 -import web3 +import CSecp256k1 import LibXMTP +import CryptoSwift enum KeyUtilError: Error { case invalidContext @@ -18,7 +13,6 @@ enum KeyUtilError: Error { case parseError } -// Copied from web3.swift since its version is `internal` enum KeyUtilx { static func generatePublicKey(from data: Data) throws -> Data { let vec = try LibXMTP.publicKeyFromPrivateKeyK256(privateKeyBytes: data) @@ -32,7 +26,7 @@ enum KeyUtilx { static func recoverPublicKeyKeccak256(from data: Data, message: Data) throws -> Data { return Data(try LibXMTP.recoverPublicKeyK256Keccak256(message: message, signature: data)) } - + static func sign(message: Data, with privateKey: Data, hashing: Bool) throws -> Data { guard let ctx = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) else { throw KeyUtilError.invalidContext @@ -72,71 +66,11 @@ enum KeyUtilx { return signature } - static func generateAddress(from publicKey: Data) -> EthereumAddress { + static func generateAddress(from publicKey: Data) -> String { let publicKeyData = publicKey.count == 64 ? publicKey : publicKey[1 ..< publicKey.count] - let hash = Util.keccak256(publicKeyData) + let hash = publicKeyData.sha3(.keccak256) let address = hash.subdata(in: 12 ..< hash.count) - return EthereumAddress("0x" + address.toHex) - } - - static func recoverPublicKey(message: Data, signature: Data) throws -> Data { - guard let ctx = secp256k1_context_create(UInt32(SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_VERIFY)) else { - throw KeyUtilError.invalidContext - } - defer { secp256k1_context_destroy(ctx) } - - // get recoverable signature - let signaturePtr = UnsafeMutablePointer.allocate(capacity: 1) - defer { signaturePtr.deallocate() } - if signature.count < 65 { - throw KeyUtilError.signatureParseFailure - } - - let serializedSignature = Data(signature[0 ..< 64]) - var v = Int32(signature[64]) - if v >= 27, v <= 30 { - v -= 27 - } else if v >= 31, v <= 34 { - v -= 31 - } else if v >= 35, v <= 38 { - v -= 35 - } - - try serializedSignature.withUnsafeBytes { - guard let baseAddress = $0.bindMemory(to: UInt8.self).baseAddress else { - throw KeyUtilError.signatureParseFailure // or a more specific error for "empty buffer" - } - if v > 3 { - throw KeyUtilError.signatureParseFailure - } - guard secp256k1_ecdsa_recoverable_signature_parse_compact(ctx, signaturePtr, baseAddress, v) == 1 else { - throw KeyUtilError.signatureParseFailure - } - } - - let pubkey = UnsafeMutablePointer.allocate(capacity: 1) - defer { pubkey.deallocate() } - - try message.withUnsafeBytes { - guard let baseAddress = $0.bindMemory(to: UInt8.self).baseAddress else { - throw KeyUtilError.signatureFailure // Consider throwing a more specific error - } - - guard secp256k1_ecdsa_recover(ctx, pubkey, signaturePtr, baseAddress) == 1 else { - throw KeyUtilError.signatureFailure - } - } - - var size = 65 - var rv = Data(count: size) - rv.withUnsafeMutableBytes { buffer -> Void in - guard let baseAddress = buffer.bindMemory(to: UInt8.self).baseAddress else { - return // Optionally, handle the error or log this condition - } - secp256k1_ec_pubkey_serialize(ctx, baseAddress, &size, pubkey, UInt32(SECP256K1_EC_UNCOMPRESSED)) - } - - return rv + return "0x" + address.toHex } } diff --git a/Sources/XMTPiOS/Messages/PrivateKey.swift b/Sources/XMTPiOS/Messages/PrivateKey.swift index 53475b0d..396041d2 100644 --- a/Sources/XMTPiOS/Messages/PrivateKey.swift +++ b/Sources/XMTPiOS/Messages/PrivateKey.swift @@ -1,4 +1,3 @@ -import CryptoKit import Foundation import LibXMTP diff --git a/Sources/XMTPiOS/Messages/PublicKey.swift b/Sources/XMTPiOS/Messages/PublicKey.swift index f83ddc7e..e92f002b 100644 --- a/Sources/XMTPiOS/Messages/PublicKey.swift +++ b/Sources/XMTPiOS/Messages/PublicKey.swift @@ -1,7 +1,5 @@ -import CryptoKit import Foundation import LibXMTP -import web3 typealias PublicKey = Xmtp_MessageContents_PublicKey @@ -11,7 +9,6 @@ enum PublicKeyError: String, Error { extension PublicKey { var walletAddress: String { - KeyUtilx.generateAddress(from: secp256K1Uncompressed.bytes) - .toChecksumAddress() + KeyUtilx.generateAddress(from: secp256K1Uncompressed.bytes).lowercased() } } diff --git a/Sources/XMTPiOS/Messages/Signature.swift b/Sources/XMTPiOS/Messages/Signature.swift index dfed671d..4af6dbf9 100644 --- a/Sources/XMTPiOS/Messages/Signature.swift +++ b/Sources/XMTPiOS/Messages/Signature.swift @@ -7,6 +7,7 @@ import Foundation import LibXMTP +import CryptoSwift /// Represents a secp256k1 compact recoverable signature. public typealias Signature = Xmtp_MessageContents_Signature @@ -42,7 +43,7 @@ extension Signature { static func ethHash(_ message: String) throws -> Data { let data = try ethPersonalMessage(message) - return Util.keccak256(data) + return data.sha3(.keccak256) } static func createIdentityText(key: Data) -> String { diff --git a/Sources/XMTPiOS/SigningKey.swift b/Sources/XMTPiOS/SigningKey.swift index ddfc2ec9..dd12b57e 100644 --- a/Sources/XMTPiOS/SigningKey.swift +++ b/Sources/XMTPiOS/SigningKey.swift @@ -1,12 +1,4 @@ -// -// SigningKey.swift -// -// -// Created by Pat Nakajima on 11/17/22. -// - import Foundation -import web3 import LibXMTP public enum WalletType { diff --git a/Sources/XMTPiOS/Util.swift b/Sources/XMTPiOS/Util.swift index d8d88dba..f72e9e18 100644 --- a/Sources/XMTPiOS/Util.swift +++ b/Sources/XMTPiOS/Util.swift @@ -6,11 +6,11 @@ // import Foundation -import web3 +import CryptoSwift enum Util { static func keccak256(_ data: Data) -> Data { - return data.web3.keccak256 + return data.sha3(.keccak256) } } diff --git a/Tests/XMTPTests/CryptoTests.swift b/Tests/XMTPTests/CryptoTests.swift index c961d051..53e87720 100644 --- a/Tests/XMTPTests/CryptoTests.swift +++ b/Tests/XMTPTests/CryptoTests.swift @@ -1,5 +1,4 @@ import XCTest -import secp256k1 @testable import XMTPiOS diff --git a/Tests/XMTPTests/DmTests.swift b/Tests/XMTPTests/DmTests.swift index c9c0b43d..a33c9e66 100644 --- a/Tests/XMTPTests/DmTests.swift +++ b/Tests/XMTPTests/DmTests.swift @@ -1,4 +1,3 @@ -import CryptoKit import LibXMTP import XCTest import XMTPTestHelpers diff --git a/Tests/XMTPTests/GroupPermissionsTests.swift b/Tests/XMTPTests/GroupPermissionsTests.swift index f650a197..43443c83 100644 --- a/Tests/XMTPTests/GroupPermissionsTests.swift +++ b/Tests/XMTPTests/GroupPermissionsTests.swift @@ -1,4 +1,3 @@ -import CryptoKit import LibXMTP import XCTest import XMTPTestHelpers diff --git a/Tests/XMTPTests/GroupTests.swift b/Tests/XMTPTests/GroupTests.swift index ebd1a069..83ef0ea6 100644 --- a/Tests/XMTPTests/GroupTests.swift +++ b/Tests/XMTPTests/GroupTests.swift @@ -1,4 +1,3 @@ -import CryptoKit import LibXMTP import XCTest import XMTPTestHelpers diff --git a/XMTP.podspec b/XMTP.podspec index dc49a473..63c9919e 100644 --- a/XMTP.podspec +++ b/XMTP.podspec @@ -1,29 +1,8 @@ -# -# Be sure to run `pod spec lint XMTP.podspec' to ensure this is a -# valid spec and to remove all comments including this before submitting the spec. -# -# To learn more about Podspec attributes see https://guides.cocoapods.org/syntax/podspec.html -# To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ -# - Pod::Spec.new do |spec| - - # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # - # - # These will help people to find your library, and whilst it - # can feel like a chore to fill in it's definitely to your advantage. The - # summary should be tweet-length, and the description more in depth. - # - spec.name = "XMTP" spec.version = "3.0.6" spec.summary = "XMTP SDK Cocoapod" - # This description is used to generate tags and improve search results. - # * Think: What does it do? Why did you write it? What is the focus? - # * Try to keep it short, snappy and to the point. - # * Write the description between the DESC delimiters below. - # * Finally, don't worry about the indent, CocoaPods strips it! spec.description = <<-DESC The XMTP cocoapod implements the XMTP protocol for iOS. It handles cryptographic operations and network communication with the XMTP network. DESC @@ -33,7 +12,7 @@ Pod::Spec.new do |spec| spec.license = "MIT" spec.author = { "XMTP" => "eng@xmtp.com" } - spec.platform = :ios, '14.0', :macos, '11.0' + spec.platform = :ios, '14.0', :macos, '11.0' spec.swift_version = '5.3' @@ -41,8 +20,10 @@ Pod::Spec.new do |spec| spec.source_files = "Sources/**/*.swift" spec.frameworks = "CryptoKit", "UIKit" - spec.dependency "web3.swift" - spec.dependency "GzipSwift" - spec.dependency "Connect-Swift", "= 0.12.0" + spec.dependency 'CSecp256k1', '~> 0.2' + spec.dependency "Connect-Swift", "= 1.0.0" spec.dependency 'LibXMTP', '= 3.0.3' + spec.dependency 'CryptoSwift', '= 1.8.3' + + spec.ios.deployment_target = '14.0' end diff --git a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.pbxproj b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.pbxproj index 325748c3..75326759 100644 --- a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.pbxproj +++ b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.pbxproj @@ -7,7 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 6AEE396E29F330CD0027B657 /* secp256k1 in Frameworks */ = {isa = PBXBuildFile; productRef = 6AEE396D29F330CD0027B657 /* secp256k1 */; }; A60FC8BF293AD054001697E3 /* MessageComposerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A60FC8BE293AD054001697E3 /* MessageComposerView.swift */; }; A60FC8C1293AD171001697E3 /* ConversationDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A60FC8C0293AD171001697E3 /* ConversationDetailView.swift */; }; A60FC8C3293AD18A001697E3 /* PreviewClientProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A60FC8C2293AD18A001697E3 /* PreviewClientProvider.swift */; }; @@ -18,26 +17,19 @@ A6557A312941166E00CC4C7B /* MessageCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6557A302941166E00CC4C7B /* MessageCellView.swift */; }; A6557A3329411F4F00CC4C7B /* NewConversationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6557A3229411F4F00CC4C7B /* NewConversationView.swift */; }; A65F0704297B5D4E00C3C76E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = A65F0703297B5D4E00C3C76E /* Persistence.swift */; }; - A65F0707297B5E7600C3C76E /* WalletConnectSwift in Frameworks */ = {isa = PBXBuildFile; productRef = A65F0706297B5E7600C3C76E /* WalletConnectSwift */; }; A65F070A297B5E8600C3C76E /* KeychainAccess in Frameworks */ = {isa = PBXBuildFile; productRef = A65F0709297B5E8600C3C76E /* KeychainAccess */; }; A6606A1A2B5EE80000E2ED4D /* XMTPiOS in Frameworks */ = {isa = PBXBuildFile; productRef = A6606A192B5EE80000E2ED4D /* XMTPiOS */; }; - A67CCEC129355B4B00131F5C /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A67CCEC029355B4B00131F5C /* AccountManager.swift */; }; A683860C293EA862006336FF /* MessageListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A683860B293EA862006336FF /* MessageListView.swift */; }; A685CC662B72B114008ACECE /* Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = A685CC652B72B114008ACECE /* Util.swift */; }; A685CC682B72B306008ACECE /* GroupSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A685CC672B72B306008ACECE /* GroupSettingsView.swift */; }; - A687810729679BC700042FAB /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = A687810629679BC700042FAB /* Account.swift */; }; - A687810C29679BFC00042FAB /* WalletConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = A687810B29679BFC00042FAB /* WalletConnection.swift */; }; - A687810E29679C0D00042FAB /* WalletConnectionMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = A687810D29679C0D00042FAB /* WalletConnectionMethod.swift */; }; A68807152B6C53E0004340BD /* GroupDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A68807142B6C53E0004340BD /* GroupDetailView.swift */; }; A69F33CA292DD557005A5556 /* LoggedInView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A69F33C9292DD557005A5556 /* LoggedInView.swift */; }; A69F33CC292DD568005A5556 /* QRCodeSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A69F33CB292DD568005A5556 /* QRCodeSheetView.swift */; }; A6C0F37B2AC1E321008C6AA7 /* Starscream in Frameworks */ = {isa = PBXBuildFile; productRef = A6C0F37A2AC1E321008C6AA7 /* Starscream */; }; - A6C0F37E2AC1E34F008C6AA7 /* WalletConnect in Frameworks */ = {isa = PBXBuildFile; productRef = A6C0F37D2AC1E34F008C6AA7 /* WalletConnect */; }; - A6C0F3802AC1E34F008C6AA7 /* WalletConnectModal in Frameworks */ = {isa = PBXBuildFile; productRef = A6C0F37F2AC1E34F008C6AA7 /* WalletConnectModal */; }; - A6C0F3822AC1E34F008C6AA7 /* Web3Wallet in Frameworks */ = {isa = PBXBuildFile; productRef = A6C0F3812AC1E34F008C6AA7 /* Web3Wallet */; }; - A6C0F3842AC1E4B5008C6AA7 /* LoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6C0F3832AC1E4B5008C6AA7 /* LoginView.swift */; }; A6C0F3862AC1E549008C6AA7 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6C0F3852AC1E549008C6AA7 /* Data.swift */; }; A6D192D0293A7B97006B49F2 /* ConversationListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6D192CF293A7B97006B49F2 /* ConversationListView.swift */; }; + E513AEA32CE6AF2700BC31C3 /* CryptoSwift in Frameworks */ = {isa = PBXBuildFile; productRef = E513AEA22CE6AF2700BC31C3 /* CryptoSwift */; }; + E583625C2CED1643003D5D00 /* CSecp256k1 in Frameworks */ = {isa = PBXBuildFile; productRef = E583625B2CED1643003D5D00 /* CSecp256k1 */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -66,17 +58,12 @@ A6557A302941166E00CC4C7B /* MessageCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageCellView.swift; sourceTree = ""; }; A6557A3229411F4F00CC4C7B /* NewConversationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationView.swift; sourceTree = ""; }; A65F0703297B5D4E00C3C76E /* Persistence.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; - A67CCEC029355B4B00131F5C /* AccountManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountManager.swift; sourceTree = ""; }; A683860B293EA862006336FF /* MessageListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageListView.swift; sourceTree = ""; }; A685CC652B72B114008ACECE /* Util.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Util.swift; sourceTree = ""; }; A685CC672B72B306008ACECE /* GroupSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupSettingsView.swift; sourceTree = ""; }; - A687810629679BC700042FAB /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; - A687810B29679BFC00042FAB /* WalletConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConnection.swift; sourceTree = ""; }; - A687810D29679C0D00042FAB /* WalletConnectionMethod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletConnectionMethod.swift; sourceTree = ""; }; A68807142B6C53E0004340BD /* GroupDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupDetailView.swift; sourceTree = ""; }; A69F33C9292DD557005A5556 /* LoggedInView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggedInView.swift; sourceTree = ""; }; A69F33CB292DD568005A5556 /* QRCodeSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeSheetView.swift; sourceTree = ""; }; - A6C0F3832AC1E4B5008C6AA7 /* LoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginView.swift; sourceTree = ""; }; A6C0F3852AC1E549008C6AA7 /* Data.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; A6D192CF293A7B97006B49F2 /* ConversationListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationListView.swift; sourceTree = ""; }; A6E774192B154D1E00F01DFF /* xmtp-ios */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "xmtp-ios"; path = ..; sourceTree = ""; }; @@ -87,12 +74,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - A65F0707297B5E7600C3C76E /* WalletConnectSwift in Frameworks */, - A6C0F3802AC1E34F008C6AA7 /* WalletConnectModal in Frameworks */, + E513AEA32CE6AF2700BC31C3 /* CryptoSwift in Frameworks */, A6606A1A2B5EE80000E2ED4D /* XMTPiOS in Frameworks */, - 6AEE396E29F330CD0027B657 /* secp256k1 in Frameworks */, - A6C0F37E2AC1E34F008C6AA7 /* WalletConnect in Frameworks */, - A6C0F3822AC1E34F008C6AA7 /* Web3Wallet in Frameworks */, + E583625C2CED1643003D5D00 /* CSecp256k1 in Frameworks */, A6C0F37B2AC1E321008C6AA7 /* Starscream in Frameworks */, A65F070A297B5E8600C3C76E /* KeychainAccess in Frameworks */, ); @@ -124,7 +108,6 @@ children = ( A6C0F3872AC1E54F008C6AA7 /* Extensions */, A65F0703297B5D4E00C3C76E /* Persistence.swift */, - A687810529679B5B00042FAB /* Account */, A69F33C8292DD54C005A5556 /* Views */, A6281992292DC825004B9117 /* XMTPiOSExampleApp.swift */, A6281994292DC825004B9117 /* ContentView.swift */, @@ -144,17 +127,6 @@ path = "Preview Content"; sourceTree = ""; }; - A687810529679B5B00042FAB /* Account */ = { - isa = PBXGroup; - children = ( - A67CCEC029355B4B00131F5C /* AccountManager.swift */, - A687810629679BC700042FAB /* Account.swift */, - A687810B29679BFC00042FAB /* WalletConnection.swift */, - A687810D29679C0D00042FAB /* WalletConnectionMethod.swift */, - ); - path = Account; - sourceTree = ""; - }; A69F33C4292DC992005A5556 /* Frameworks */ = { isa = PBXGroup; children = ( @@ -174,7 +146,6 @@ A683860B293EA862006336FF /* MessageListView.swift */, A6557A302941166E00CC4C7B /* MessageCellView.swift */, A6557A3229411F4F00CC4C7B /* NewConversationView.swift */, - A6C0F3832AC1E4B5008C6AA7 /* LoginView.swift */, A68807142B6C53E0004340BD /* GroupDetailView.swift */, A685CC672B72B306008ACECE /* GroupSettingsView.swift */, ); @@ -208,14 +179,11 @@ ); name = XMTPiOSExample; packageProductDependencies = ( - A65F0706297B5E7600C3C76E /* WalletConnectSwift */, A65F0709297B5E8600C3C76E /* KeychainAccess */, - 6AEE396D29F330CD0027B657 /* secp256k1 */, A6C0F37A2AC1E321008C6AA7 /* Starscream */, - A6C0F37D2AC1E34F008C6AA7 /* WalletConnect */, - A6C0F37F2AC1E34F008C6AA7 /* WalletConnectModal */, - A6C0F3812AC1E34F008C6AA7 /* Web3Wallet */, A6606A192B5EE80000E2ED4D /* XMTPiOS */, + E513AEA22CE6AF2700BC31C3 /* CryptoSwift */, + E583625B2CED1643003D5D00 /* CSecp256k1 */, ); productName = XMTPiOSExample; productReference = A628198F292DC825004B9117 /* XMTPiOSExample.app */; @@ -246,11 +214,10 @@ ); mainGroup = A6281986292DC825004B9117; packageReferences = ( - A65F0705297B5E7500C3C76E /* XCRemoteSwiftPackageReference "WalletConnectSwift" */, A65F0708297B5E8600C3C76E /* XCRemoteSwiftPackageReference "KeychainAccess" */, - 6AEE396C29F330CD0027B657 /* XCRemoteSwiftPackageReference "secp256k1.swift" */, A6C0F3792AC1E321008C6AA7 /* XCRemoteSwiftPackageReference "Starscream" */, - A6C0F37C2AC1E34F008C6AA7 /* XCRemoteSwiftPackageReference "WalletConnectSwiftV2" */, + E513AEA12CE6AF2700BC31C3 /* XCRemoteSwiftPackageReference "CryptoSwift" */, + E583625A2CED1643003D5D00 /* XCRemoteSwiftPackageReference "CSecp256k1.swift" */, ); productRefGroup = A6281990292DC825004B9117 /* Products */; projectDirPath = ""; @@ -304,20 +271,15 @@ A68807152B6C53E0004340BD /* GroupDetailView.swift in Sources */, A6C0F3862AC1E549008C6AA7 /* Data.swift in Sources */, A65F0704297B5D4E00C3C76E /* Persistence.swift in Sources */, - A687810729679BC700042FAB /* Account.swift in Sources */, A6557A312941166E00CC4C7B /* MessageCellView.swift in Sources */, A60FC8C1293AD171001697E3 /* ConversationDetailView.swift in Sources */, A685CC682B72B306008ACECE /* GroupSettingsView.swift in Sources */, A685CC662B72B114008ACECE /* Util.swift in Sources */, A60FC8C3293AD18A001697E3 /* PreviewClientProvider.swift in Sources */, A6281995292DC825004B9117 /* ContentView.swift in Sources */, - A687810C29679BFC00042FAB /* WalletConnection.swift in Sources */, A69F33CA292DD557005A5556 /* LoggedInView.swift in Sources */, A69F33CC292DD568005A5556 /* QRCodeSheetView.swift in Sources */, - A6C0F3842AC1E4B5008C6AA7 /* LoginView.swift in Sources */, A6281993292DC825004B9117 /* XMTPiOSExampleApp.swift in Sources */, - A67CCEC129355B4B00131F5C /* AccountManager.swift in Sources */, - A687810E29679C0D00042FAB /* WalletConnectionMethod.swift in Sources */, A60FC8BF293AD054001697E3 /* MessageComposerView.swift in Sources */, A683860C293EA862006336FF /* MessageListView.swift in Sources */, A6D192D0293A7B97006B49F2 /* ConversationListView.swift in Sources */, @@ -541,22 +503,6 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 6AEE396C29F330CD0027B657 /* XCRemoteSwiftPackageReference "secp256k1.swift" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/GigaBitcoin/secp256k1.swift.git"; - requirement = { - kind = exactVersion; - version = 0.10.0; - }; - }; - A65F0705297B5E7500C3C76E /* XCRemoteSwiftPackageReference "WalletConnectSwift" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/WalletConnect/WalletConnectSwift"; - requirement = { - branch = master; - kind = branch; - }; - }; A65F0708297B5E8600C3C76E /* XCRemoteSwiftPackageReference "KeychainAccess" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/kishikawakatsumi/KeychainAccess"; @@ -573,27 +519,25 @@ version = 3.1.2; }; }; - A6C0F37C2AC1E34F008C6AA7 /* XCRemoteSwiftPackageReference "WalletConnectSwiftV2" */ = { + E513AEA12CE6AF2700BC31C3 /* XCRemoteSwiftPackageReference "CryptoSwift" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/WalletConnect/WalletConnectSwiftV2"; + repositoryURL = "https://github.com/krzyzanowskim/CryptoSwift.git"; requirement = { - kind = exactVersion; - version = 1.9.8; + kind = upToNextMajorVersion; + minimumVersion = 1.8.3; + }; + }; + E583625A2CED1643003D5D00 /* XCRemoteSwiftPackageReference "CSecp256k1.swift" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/tesseract-one/CSecp256k1.swift.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 0.2.0; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 6AEE396D29F330CD0027B657 /* secp256k1 */ = { - isa = XCSwiftPackageProductDependency; - package = 6AEE396C29F330CD0027B657 /* XCRemoteSwiftPackageReference "secp256k1.swift" */; - productName = secp256k1; - }; - A65F0706297B5E7600C3C76E /* WalletConnectSwift */ = { - isa = XCSwiftPackageProductDependency; - package = A65F0705297B5E7500C3C76E /* XCRemoteSwiftPackageReference "WalletConnectSwift" */; - productName = WalletConnectSwift; - }; A65F0709297B5E8600C3C76E /* KeychainAccess */ = { isa = XCSwiftPackageProductDependency; package = A65F0708297B5E8600C3C76E /* XCRemoteSwiftPackageReference "KeychainAccess" */; @@ -608,20 +552,15 @@ package = A6C0F3792AC1E321008C6AA7 /* XCRemoteSwiftPackageReference "Starscream" */; productName = Starscream; }; - A6C0F37D2AC1E34F008C6AA7 /* WalletConnect */ = { - isa = XCSwiftPackageProductDependency; - package = A6C0F37C2AC1E34F008C6AA7 /* XCRemoteSwiftPackageReference "WalletConnectSwiftV2" */; - productName = WalletConnect; - }; - A6C0F37F2AC1E34F008C6AA7 /* WalletConnectModal */ = { + E513AEA22CE6AF2700BC31C3 /* CryptoSwift */ = { isa = XCSwiftPackageProductDependency; - package = A6C0F37C2AC1E34F008C6AA7 /* XCRemoteSwiftPackageReference "WalletConnectSwiftV2" */; - productName = WalletConnectModal; + package = E513AEA12CE6AF2700BC31C3 /* XCRemoteSwiftPackageReference "CryptoSwift" */; + productName = CryptoSwift; }; - A6C0F3812AC1E34F008C6AA7 /* Web3Wallet */ = { + E583625B2CED1643003D5D00 /* CSecp256k1 */ = { isa = XCSwiftPackageProductDependency; - package = A6C0F37C2AC1E34F008C6AA7 /* XCRemoteSwiftPackageReference "WalletConnectSwiftV2" */; - productName = Web3Wallet; + package = E583625A2CED1643003D5D00 /* XCRemoteSwiftPackageReference "CSecp256k1.swift" */; + productName = CSecp256k1; }; /* End XCSwiftPackageProductDependency section */ }; diff --git a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4f6d7203..21d422e2 100644 --- a/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/XMTPiOSExample/XMTPiOSExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,21 +1,12 @@ { "pins" : [ - { - "identity" : "bigint", - "kind" : "remoteSourceControl", - "location" : "https://github.com/attaswift/BigInt", - "state" : { - "revision" : "0ed110f7555c34ff468e72e1686e59721f2b0da6", - "version" : "5.3.0" - } - }, { "identity" : "connect-swift", "kind" : "remoteSourceControl", "location" : "https://github.com/bufbuild/connect-swift", "state" : { - "revision" : "1701d3d1b2c4c63fcccfd7094f86a88672fa5acb", - "version" : "0.12.0" + "revision" : "a8c984a1077f78e94e0884c5c11683a7f684f92c", + "version" : "1.0.0" } }, { @@ -23,26 +14,17 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/krzyzanowskim/CryptoSwift.git", "state" : { - "revision" : "039f56c5d7960f277087a0be51f5eb04ed0ec073", - "version" : "1.5.1" + "revision" : "678d442c6f7828def400a70ae15968aef67ef52d", + "version" : "1.8.3" } }, { - "identity" : "generic-json-swift", + "identity" : "csecp256k1.swift", "kind" : "remoteSourceControl", - "location" : "https://github.com/iwill/generic-json-swift", + "location" : "https://github.com/tesseract-one/CSecp256k1.swift.git", "state" : { - "revision" : "0a06575f4038b504e78ac330913d920f1630f510", - "version" : "2.0.2" - } - }, - { - "identity" : "gzipswift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/1024jp/GzipSwift", - "state" : { - "revision" : "7a7f17761c76a932662ab77028a4329f67d645a4", - "version" : "5.2.0" + "revision" : "cfbd6f540d5084bc96a60af841121472fbe725a3", + "version" : "0.2.0" } }, { @@ -63,24 +45,6 @@ "version" : "3.0.3" } }, - { - "identity" : "qrcode", - "kind" : "remoteSourceControl", - "location" : "https://github.com/WalletConnect/QRCode", - "state" : { - "revision" : "263f280d2c8144adfb0b6676109846cfc8dd552b", - "version" : "14.3.1" - } - }, - { - "identity" : "secp256k1.swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/GigaBitcoin/secp256k1.swift.git", - "state" : { - "revision" : "48fb20fce4ca3aad89180448a127d5bc16f0e44c", - "version" : "0.10.0" - } - }, { "identity" : "starscream", "kind" : "remoteSourceControl", @@ -113,53 +77,26 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-docc-plugin.git", "state" : { - "revision" : "26ac5758409154cc448d7ab82389c520fa8a8247", - "version" : "1.3.0" + "revision" : "85e4bb4e1cd62cec64a4b8e769dcefdf0c5b9d64", + "version" : "1.4.3" } }, { "identity" : "swift-docc-symbolkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-docc-symbolkit", + "location" : "https://github.com/swiftlang/swift-docc-symbolkit", "state" : { "revision" : "b45d1f2ed151d057b54504d653e0da5552844e34", "version" : "1.0.0" } }, - { - "identity" : "swift-http-types", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-http-types", - "state" : { - "revision" : "99d066e29effa8845e4761dd3f2f831edfdf8925", - "version" : "1.0.0" - } - }, - { - "identity" : "swift-log", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-log.git", - "state" : { - "revision" : "532d8b529501fb73a2455b179e0bbb6d49b652ed", - "version" : "1.5.3" - } - }, { "identity" : "swift-nio", "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio.git", "state" : { - "revision" : "fc63f0cf4e55a4597407a9fc95b16a2bc44b4982", - "version" : "2.64.0" - } - }, - { - "identity" : "swift-nio-extras", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-extras.git", - "state" : { - "revision" : "798c962495593a23fdea0c0c63fd55571d8dff51", - "version" : "1.20.0" + "revision" : "914081701062b11e3bb9e21accc379822621995e", + "version" : "2.76.1" } }, { @@ -167,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-http2.git", "state" : { - "revision" : "0904bf0feb5122b7e5c3f15db7df0eabe623dd87", - "version" : "1.30.0" + "revision" : "eaa71bb6ae082eee5a07407b1ad0cbd8f48f9dca", + "version" : "1.34.1" } }, { @@ -176,17 +113,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-nio-ssl.git", "state" : { - "revision" : "7c381eb6083542b124a6c18fae742f55001dc2b5", - "version" : "2.26.0" - } - }, - { - "identity" : "swift-nio-transport-services", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-nio-transport-services.git", - "state" : { - "revision" : "ebf8b9c365a6ce043bf6e6326a04b15589bd285e", - "version" : "1.20.0" + "revision" : "c7e95421334b1068490b5d41314a50e70bab23d1", + "version" : "2.29.0" } }, { @@ -194,17 +122,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-protobuf.git", "state" : { - "revision" : "65e8f29b2d63c4e38e736b25c27b83e012159be8", - "version" : "1.25.2" - } - }, - { - "identity" : "swift-qrcode-generator", - "kind" : "remoteSourceControl", - "location" : "https://github.com/dagronf/swift-qrcode-generator", - "state" : { - "revision" : "5ca09b6a2ad190f94aa3d6ddef45b187f8c0343b", - "version" : "1.0.3" + "revision" : "ebc7251dd5b37f627c93698e4374084d98409633", + "version" : "1.28.2" } }, { @@ -212,53 +131,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/apple/swift-system.git", "state" : { - "revision" : "025bcb1165deab2e20d4eaba79967ce73013f496", - "version" : "1.2.1" - } - }, - { - "identity" : "swiftimagereadwrite", - "kind" : "remoteSourceControl", - "location" : "https://github.com/dagronf/SwiftImageReadWrite", - "state" : { - "revision" : "5596407d1cf61b953b8e658fa8636a471df3c509", - "version" : "1.1.6" - } - }, - { - "identity" : "walletconnectswift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/WalletConnect/WalletConnectSwift", - "state" : { - "branch" : "master", - "revision" : "9e4dfba34fb35336fd5da551285d7986ff536cb8" - } - }, - { - "identity" : "walletconnectswiftv2", - "kind" : "remoteSourceControl", - "location" : "https://github.com/WalletConnect/WalletConnectSwiftV2", - "state" : { - "revision" : "addf9a3688ef5e5d9d148ecbb30ca0fd3132b908", - "version" : "1.9.8" - } - }, - { - "identity" : "web3.swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/argentlabs/web3.swift", - "state" : { - "revision" : "8ca33e700ed8de6137a0e1471017aa3b3c8de0db", - "version" : "1.6.0" - } - }, - { - "identity" : "websocket-kit", - "kind" : "remoteSourceControl", - "location" : "https://github.com/vapor/websocket-kit.git", - "state" : { - "revision" : "53fe0639a98903858d0196b699720decb42aee7b", - "version" : "2.14.0" + "revision" : "c8a44d836fe7913603e246acab7c528c2e780168", + "version" : "1.4.0" } } ], diff --git a/XMTPiOSExample/XMTPiOSExample/Account/Account.swift b/XMTPiOSExample/XMTPiOSExample/Account/Account.swift deleted file mode 100644 index a0acfb79..00000000 --- a/XMTPiOSExample/XMTPiOSExample/Account/Account.swift +++ /dev/null @@ -1,58 +0,0 @@ -// -// Account.swift -// -// -// Created by Pat Nakajima on 11/22/22. -// -import Foundation -import XMTPiOS - -/// Wrapper around a WalletConnect V1 wallet connection. Account conforms to ``SigningKey`` so -/// you can use it to create a ``Client``. -/// -/// > Warning: The WalletConnect V1 API will be deprecated soon. -public struct Account { - var connection: WalletConnection - - public static func create() throws -> Account { - let connection = WCWalletConnection() - return try Account(connection: connection) - } - - init(connection: WalletConnection) throws { - self.connection = connection - } - - public var isConnected: Bool { - connection.isConnected - } - - public var address: String { - connection.walletAddress ?? "" - } - - public func preferredConnectionMethod() throws -> WalletConnectionMethodType { - try connection.preferredConnectionMethod() - } - - public func connect() async throws { - try await connection.connect() - } -} - -extension Account: SigningKey { - public func sign(_ data: Data) async throws -> Signature { - let signatureData = try await connection.sign(data) - - var signature = Signature() - - signature.ecdsaCompact.bytes = signatureData[0 ..< 64] - signature.ecdsaCompact.recovery = UInt32(signatureData[64]) - - return signature - } - - public func sign(message: String) async throws -> Signature { - return try await sign(Data(message.utf8)) - } -} diff --git a/XMTPiOSExample/XMTPiOSExample/Account/AccountManager.swift b/XMTPiOSExample/XMTPiOSExample/Account/AccountManager.swift deleted file mode 100644 index 9dd31539..00000000 --- a/XMTPiOSExample/XMTPiOSExample/Account/AccountManager.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// AccountManager.swift -// XMTPiOSExample -// -// Created by Pat Nakajima on 11/22/22. -// - -import Foundation -import XMTPiOS - -class AccountManager: ObservableObject { - var account: Account - - init() { - do { - account = try Account.create() - } catch { - fatalError("Account could not be created: \(error)") - } - } -} diff --git a/XMTPiOSExample/XMTPiOSExample/Account/WalletConnection.swift b/XMTPiOSExample/XMTPiOSExample/Account/WalletConnection.swift deleted file mode 100644 index 5666ef8c..00000000 --- a/XMTPiOSExample/XMTPiOSExample/Account/WalletConnection.swift +++ /dev/null @@ -1,196 +0,0 @@ -// -// WalletConnection.swift -// -// -// Created by Pat Nakajima on 11/22/22. -// - -import Foundation -import UIKit -import WalletConnectSwift -import web3 -import XMTPiOS - -extension WCURL { - var asURL: URL { - // swiftlint:disable force_unwrapping - URL(string: "wc://wc?uri=\(absoluteString)")! - // swiftlint:enable force_unwrapping - } -} - -enum WalletConnectionError: String, Error { - case walletConnectURL - case noSession - case noAddress - case invalidMessage - case noSignature -} - -protocol WalletConnection { - var isConnected: Bool { get } - var walletAddress: String? { get } - func preferredConnectionMethod() throws -> WalletConnectionMethodType - func connect() async throws - func sign(_ data: Data) async throws -> Data -} - -class WCWalletConnection: WalletConnection, WalletConnectSwift.ClientDelegate { - @Published public var isConnected = false - - var walletConnectClient: WalletConnectSwift.Client! - var session: WalletConnectSwift.Session? { - didSet { - DispatchQueue.main.async { - self.isConnected = self.session != nil - } - } - } - - init() { - let peerMeta = Session.ClientMeta( - name: "xmtp-ios", - description: "XMTP", - icons: [], - // swiftlint:disable force_unwrapping - url: URL(string: "https://safe.gnosis.io")! - // swiftlint:enable force_unwrapping - ) - let dAppInfo = WalletConnectSwift.Session.DAppInfo(peerId: UUID().uuidString, peerMeta: peerMeta) - - walletConnectClient = WalletConnectSwift.Client(delegate: self, dAppInfo: dAppInfo) - } - - @MainActor func preferredConnectionMethod() throws -> WalletConnectionMethodType { - guard let url = walletConnectURL?.asURL else { - throw WalletConnectionError.walletConnectURL - } - - if UIApplication.shared.canOpenURL(url) { - return WalletRedirectConnectionMethod(redirectURI: url.absoluteString).type - } - - return WalletQRCodeConnectionMethod(redirectURI: url.absoluteString).type - } - - lazy var walletConnectURL: WCURL? = { - do { - let keybytes = try secureRandomBytes(count: 32) - - return WCURL( - topic: UUID().uuidString, - // swiftlint:disable force_unwrapping - bridgeURL: URL(string: "https://bridge.walletconnect.org")!, - // swiftlint:enable force_unwrapping - key: keybytes.reduce("") { $0 + String(format: "%02x", $1) } - ) - } catch { - return nil - } - }() - - func secureRandomBytes(count: Int) throws -> Data { - var bytes = [UInt8](repeating: 0, count: count) - - // Fill bytes with secure random data - let status = SecRandomCopyBytes( - kSecRandomDefault, - count, - &bytes - ) - - // A status of errSecSuccess indicates success - if status == errSecSuccess { - return Data(bytes) - } else { - fatalError("could not generate random bytes") - } - } - - func connect() async throws { - guard let url = walletConnectURL else { - throw WalletConnectionError.walletConnectURL - } - - try walletConnectClient.connect(to: url) - } - - func sign(_ data: Data) async throws -> Data { - guard session != nil else { - throw WalletConnectionError.noSession - } - - guard let walletAddress = walletAddress else { - throw WalletConnectionError.noAddress - } - - guard let url = walletConnectURL else { - throw WalletConnectionError.walletConnectURL - } - - guard let message = String(data: data, encoding: .utf8) else { - throw WalletConnectionError.invalidMessage - } - - return try await withCheckedThrowingContinuation { continuation in - do { - try walletConnectClient.personal_sign(url: url, message: message, account: walletAddress) { response in - if let error = response.error { - continuation.resume(throwing: error) - return - } - - do { - var resultString = try response.result(as: String.self) - - // Strip leading 0x that we get back from `personal_sign` - if resultString.hasPrefix("0x"), resultString.count == 132 { - resultString = String(resultString.dropFirst(2)) - } - - guard let resultDataBytes = resultString.web3.bytesFromHex else { - continuation.resume(throwing: WalletConnectionError.noSignature) - return - } - - var resultData = Data(resultDataBytes) - - // Ensure we have a valid recovery byte - resultData[resultData.count - 1] = 1 - resultData[resultData.count - 1] % 2 - - continuation.resume(returning: resultData) - } catch { - continuation.resume(throwing: error) - } - } - } catch { - continuation.resume(throwing: error) - } - } - } - - var walletAddress: String? { - if let address = session?.walletInfo?.accounts.first { - return EthereumAddress(address).toChecksumAddress() - } - - return nil - } - - func client(_: WalletConnectSwift.Client, didConnect _: WalletConnectSwift.WCURL) {} - - func client(_: WalletConnectSwift.Client, didFailToConnect _: WalletConnectSwift.WCURL) {} - - func client(_: WalletConnectSwift.Client, didConnect session: WalletConnectSwift.Session) { - // Future Implementation Cache session - self.session = session - } - - func client(_: WalletConnectSwift.Client, didUpdate session: WalletConnectSwift.Session) { - self.session = session - } - - func client(_: WalletConnectSwift.Client, didDisconnect _: WalletConnectSwift.Session) { - session = nil - } -} diff --git a/XMTPiOSExample/XMTPiOSExample/Account/WalletConnectionMethod.swift b/XMTPiOSExample/XMTPiOSExample/Account/WalletConnectionMethod.swift deleted file mode 100644 index 35c718ac..00000000 --- a/XMTPiOSExample/XMTPiOSExample/Account/WalletConnectionMethod.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// WalletConnectionMethod.swift -// -// -// Created by Pat Nakajima on 11/22/22. -// - -import CoreImage.CIFilterBuiltins -import UIKit -import WalletConnectSwift - -protocol WalletConnectionMethod { - var type: WalletConnectionMethodType { get } -} - -/// Describes WalletConnect flows. -public enum WalletConnectionMethodType { - case redirect(URL), qrCode(UIImage), manual(String) -} - -struct WalletRedirectConnectionMethod: WalletConnectionMethod { - var redirectURI: String - var type: WalletConnectionMethodType { - // swiftlint:disable force_unwrapping - .redirect(URL(string: redirectURI)!) - // swiftlint:enable force_unwrapping - } -} - -struct WalletQRCodeConnectionMethod: WalletConnectionMethod { - var redirectURI: String - var type: WalletConnectionMethodType { - let data = Data(redirectURI.utf8) - let context = CIContext() - let filter = CIFilter.qrCodeGenerator() - filter.setValue(data, forKey: "inputMessage") - - // swiftlint:disable force_unwrapping - let outputImage = filter.outputImage! - let scaledImage = outputImage.transformed(by: CGAffineTransform(scaleX: 3, y: 3)) - let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent)! - // swiftlint:enable force_unwrapping - - let image = UIImage(cgImage: cgImage) - - return .qrCode(image) - } -} - -struct WalletManualConnectionMethod: WalletConnectionMethod { - var redirectURI: String - var type: WalletConnectionMethodType { - .manual(redirectURI) - } -} diff --git a/XMTPiOSExample/XMTPiOSExample/ContentView.swift b/XMTPiOSExample/XMTPiOSExample/ContentView.swift index 33e4de7f..d5fafb79 100644 --- a/XMTPiOSExample/XMTPiOSExample/ContentView.swift +++ b/XMTPiOSExample/XMTPiOSExample/ContentView.swift @@ -13,7 +13,6 @@ struct ContentView: View { case unknown, connecting, connected(Client), error(String) } - @StateObject var accountManager = AccountManager() @State private var status: Status = .unknown @@ -27,18 +26,6 @@ struct ContentView: View { VStack { switch status { case .unknown: - Button("Connect Wallet") { isConnectingWallet = true } - .sheet(isPresented: $isConnectingWallet) { - LoginView(onConnected: { client in - do { - self.status = .connected(client) - } catch { - print("Error setting up client: \(error)") - } - - print("Got a client: \(client)") - }) - } Button("Generate Wallet") { generateWallet() } Button("Load Saved Keys") { Task { diff --git a/XMTPiOSExample/XMTPiOSExample/Views/LoginView.swift b/XMTPiOSExample/XMTPiOSExample/Views/LoginView.swift deleted file mode 100644 index ebd27837..00000000 --- a/XMTPiOSExample/XMTPiOSExample/Views/LoginView.swift +++ /dev/null @@ -1,194 +0,0 @@ -// -// LoginView.swift -// XMTPChat -// -// Created by Pat Nakajima on 6/7/23. -// - -import SwiftUI -import Combine -import WebKit -import XMTPiOS -import WalletConnectRelay -import WalletConnectModal -import Starscream - -extension WebSocket: WebSocketConnecting { } -extension Blockchain: @unchecked Sendable { } - -struct SocketFactory: WebSocketFactory { - func create(with url: URL) -> WalletConnectRelay.WebSocketConnecting { - WebSocket(url: url) - } -} - -// WalletConnectV2's ModalSheet doesn't have any public initializers so we need -// to wrap their UIKit API -struct ModalWrapper: UIViewControllerRepresentable { - func makeUIViewController(context: Context) -> UIViewController { - let controller = UIViewController() - Task { - try? await Task.sleep(for: .seconds(0.4)) - await MainActor.run { - WalletConnectModal.present(from: controller) - } - } - return controller - } - - func updateUIViewController(_ uiViewController: UIViewController, context: Context) { - } -} - -// Conformance to XMTP iOS's SigningKey protocol -class Signer: SigningKey { - var account: WalletConnectUtils.Account - var session: WalletConnectSign.Session - - var address: String { - account.address - } - - init(session: WalletConnectSign.Session, account: WalletConnectUtils.Account) { - self.session = session - self.account = account - self.cancellable = Sign.instance.sessionResponsePublisher.sink { response in - guard case let .response(codable) = response.result else { - return - } - - // swiftlint:disable force_cast - let signatureData = Data(hexString: codable.value as! String) - // swiftlint:enable force_cast - let signature = Signature(bytes: signatureData[0..<64], recovery: Int(signatureData[64])) - - self.continuation?.resume(returning: signature) - self.continuation = nil - } - } - - var cancellable: AnyCancellable? - var continuation: CheckedContinuation? - - func sign(_ data: Data) async throws -> Signature { - let address = account.address - let topic = session.topic - let blockchain = account.blockchain - - return await withCheckedContinuation { continuation in - self.continuation = continuation - - Task { - let method = "personal_sign" - let walletAddress = address - let requestParams = AnyCodable([ - String(data: data, encoding: .utf8), - walletAddress - ]) - - let request = Request( - topic: topic, - method: method, - params: requestParams, - chainId: blockchain - ) - - try await Sign.instance.request(params: request) - } - } - } - - func sign(message: String) async throws -> Signature { - try await sign(Data(message.utf8)) - } -} - -struct LoginView: View { - var onConnected: (Client) -> Void - var publishers: [AnyCancellable] = [] - - @State private var isShowingWebview = true - // swiftlint:disable function_body_length - init( - onConnected: @escaping (Client) -> Void - ) { - self.onConnected = onConnected - - Networking.configure( - projectId: "YOUR PROJECT ID", - socketFactory: SocketFactory() - ) - - WalletConnectModal.configure( - projectId: "YOUR PROJECT ID", - metadata: .init( - name: "XMTP Chat", - description: "It's a chat app.", - url: "https://localhost:4567", - icons: [], - redirect: AppMetadata.Redirect( - native: "", - universal: nil - ) - ) - ) - - let requiredNamespaces: [String: ProposalNamespace] = [:] - let optionalNamespaces: [String: ProposalNamespace] = [ - "eip155": ProposalNamespace( - chains: [ - // swiftlint:disable force_unwrapping - Blockchain("eip155:80001")!, // Polygon Testnet - Blockchain("eip155:421613")! // Arbitrum Testnet - // swiftlint:enable force_unwrapping - ], - methods: [ - "personal_sign" - ], events: [] - ) - ] - - WalletConnectModal.set(sessionParams: .init( - requiredNamespaces: requiredNamespaces, - optionalNamespaces: optionalNamespaces, - sessionProperties: nil - )) - - Sign.instance.sessionSettlePublisher - .receive(on: DispatchQueue.main) - .sink { session in - guard let account = session.accounts.first else { return } - - Task(priority: .high) { - let signer = Signer(session: session, account: account) - let key = try secureRandomBytes(count: 32) - Persistence().saveKeys(key) - Persistence().saveAddress(signer.address) - let client = try await Client.create( - account: signer, - options: .init( - api: .init(env: .local, isSecure: false), - codecs: [GroupUpdatedCodec()], - dbEncryptionKey: key - ) - ) - - await MainActor.run { - onConnected(client) - } - } - - print("GOT AN ACCOUNT \(account)") - } - .store(in: &publishers) - } - // swiftlint:enable function_body_length - - var body: some View { - ModalWrapper() - } -} - -#Preview { - LoginView(onConnected: { _ in }) -} diff --git a/XMTPiOSExample/XMTPiOSExample/Views/MessageCellView.swift b/XMTPiOSExample/XMTPiOSExample/Views/MessageCellView.swift index 71105cc6..f7483ab9 100644 --- a/XMTPiOSExample/XMTPiOSExample/Views/MessageCellView.swift +++ b/XMTPiOSExample/XMTPiOSExample/Views/MessageCellView.swift @@ -7,7 +7,6 @@ import SwiftUI import XMTPiOS -import web3 struct MessageTextView: View { var myAddress: String @@ -126,14 +125,3 @@ struct MessageCellView: View { } } } - -struct MessageCellView_Previews: PreviewProvider { - static var previews: some View { - PreviewClientProvider { client in - List { - MessageCellView(myAddress: "0x00", message: DecodedMessage.preview(client: client, topic: "foo", body: "Hi, how is it going?", senderAddress: "0x00", sent: Date())) - } - .listStyle(.plain) - } - } -} diff --git a/XMTPiOSExample/XMTPiOSExample/Views/MessageListView.swift b/XMTPiOSExample/XMTPiOSExample/Views/MessageListView.swift index 087035ec..258b6c1d 100644 --- a/XMTPiOSExample/XMTPiOSExample/Views/MessageListView.swift +++ b/XMTPiOSExample/XMTPiOSExample/Views/MessageListView.swift @@ -39,22 +39,3 @@ struct MessageListView: View { } } } - -struct MessageListView_Previews: PreviewProvider { - static var previews: some View { - PreviewClientProvider { client in - // swiftlint: disable comma - MessageListView( - myAddress: "0x00", messages: [ - DecodedMessage.preview(client: client, topic: "foo", body: "Hello", senderAddress: "0x00", sent: Date().addingTimeInterval(-10)), - DecodedMessage.preview(client: client, topic: "foo",body: "Oh hi", senderAddress: "0x01", sent: Date().addingTimeInterval(-9)), - DecodedMessage.preview(client: client, topic: "foo",body: "Sup", senderAddress: "0x01", sent: Date().addingTimeInterval(-8)), - DecodedMessage.preview(client: client, topic: "foo",body: "Nice to see you", senderAddress: "0x00", sent: Date().addingTimeInterval(-7)), - DecodedMessage.preview(client: client, topic: "foo",body: "What if it's a longer message I mean really really long like should it wrap?", senderAddress: "0x01", sent: Date().addingTimeInterval(-6)), - DecodedMessage.preview(client: client, topic: "foo",body: "🧐", senderAddress: "0x00", sent: Date().addingTimeInterval(-5)), - ] - ) - // swiftlint: enable comma - } - } -}