diff --git a/stellarsdk/stellarsdk.xcodeproj/project.pbxproj b/stellarsdk/stellarsdk.xcodeproj/project.pbxproj index 70824dab..28f1f9f2 100644 --- a/stellarsdk/stellarsdk.xcodeproj/project.pbxproj +++ b/stellarsdk/stellarsdk.xcodeproj/project.pbxproj @@ -768,6 +768,8 @@ 83379C2C2280BE2A00BD5F8E /* CreatePassiveSellOfferOperationResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83379C262280B64500BD5F8E /* CreatePassiveSellOfferOperationResponse.swift */; }; 83379C2E2280CF9C00BD5F8E /* CreatePassiveSellOfferOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83379C2D2280CF9C00BD5F8E /* CreatePassiveSellOfferOperation.swift */; }; 83379C2F2280CF9C00BD5F8E /* CreatePassiveSellOfferOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83379C2D2280CF9C00BD5F8E /* CreatePassiveSellOfferOperation.swift */; }; + 8339DA5B2D36A55200232C8B /* ISO8601DateFormatter+Full.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8339DA5A2D36A55200232C8B /* ISO8601DateFormatter+Full.swift */; }; + 8339DA5C2D36A55300232C8B /* ISO8601DateFormatter+Full.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8339DA5A2D36A55200232C8B /* ISO8601DateFormatter+Full.swift */; }; 833C67282B84C85000E034C6 /* QuoteService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833C67272B84C85000E034C6 /* QuoteService.swift */; }; 833C67292B84C85000E034C6 /* QuoteService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833C67272B84C85000E034C6 /* QuoteService.swift */; }; 833C672C2B84C97000E034C6 /* Sep38Responses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 833C672B2B84C97000E034C6 /* Sep38Responses.swift */; }; @@ -1686,6 +1688,7 @@ 83379C242280AE9C00BD5F8E /* ManageBuyOfferOperationResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManageBuyOfferOperationResponse.swift; sourceTree = ""; }; 83379C262280B64500BD5F8E /* CreatePassiveSellOfferOperationResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePassiveSellOfferOperationResponse.swift; sourceTree = ""; }; 83379C2D2280CF9C00BD5F8E /* CreatePassiveSellOfferOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreatePassiveSellOfferOperation.swift; sourceTree = ""; }; + 8339DA5A2D36A55200232C8B /* ISO8601DateFormatter+Full.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ISO8601DateFormatter+Full.swift"; sourceTree = ""; }; 833C67272B84C85000E034C6 /* QuoteService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuoteService.swift; sourceTree = ""; }; 833C672B2B84C97000E034C6 /* Sep38Responses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sep38Responses.swift; sourceTree = ""; }; 833C672F2B84CF2F00E034C6 /* Sep38PostQuoteRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sep38PostQuoteRequest.swift; sourceTree = ""; }; @@ -2374,6 +2377,7 @@ 74A504ED2192CC0000A608A0 /* String+KeyUtils.swift */, 74A504F02192D5D600A608A0 /* Data+KeyUtils.swift */, 83DD714F281DE65C00530C64 /* Data+B16.swift */, + 8339DA5A2D36A55200232C8B /* ISO8601DateFormatter+Full.swift */, ); path = extensions; sourceTree = ""; @@ -4495,6 +4499,7 @@ 745DF4E92052FF9C000D3660 /* Blowfish.swift in Sources */, 745DF4EA2052FF9C000D3660 /* DigestType.swift in Sources */, 745DF4EB2052FF9C000D3660 /* Utils.swift in Sources */, + 8339DA5C2D36A55300232C8B /* ISO8601DateFormatter+Full.swift in Sources */, 830E7DBC2529E24B0059A4B4 /* TrustlineSponsorshipUpdatedEffectResponse.swift in Sources */, 8320A9F1251E6ED6002FE6FA /* CreateClaimableBalanceResultXDR.swift in Sources */, 83B827822B306E1F0064D7CB /* SimulateTransactionRequest.swift in Sources */, @@ -5186,6 +5191,7 @@ 744C4DBF202A29E400B46CDE /* AccountCreatedOperationResponse.swift in Sources */, EC34A0D020503CAB000FB042 /* RIPEMD160.swift in Sources */, EC34A11A20503CC5000FB042 /* HKDF.swift in Sources */, + 8339DA5B2D36A55200232C8B /* ISO8601DateFormatter+Full.swift in Sources */, 830E7DBB2529E24B0059A4B4 /* TrustlineSponsorshipUpdatedEffectResponse.swift in Sources */, 8320A9F0251E6ED6002FE6FA /* CreateClaimableBalanceResultXDR.swift in Sources */, 83B827812B306E1F0064D7CB /* SimulateTransactionRequest.swift in Sources */, diff --git a/stellarsdk/stellarsdk/extensions/ISO8601DateFormatter+Full.swift b/stellarsdk/stellarsdk/extensions/ISO8601DateFormatter+Full.swift new file mode 100644 index 00000000..66758952 --- /dev/null +++ b/stellarsdk/stellarsdk/extensions/ISO8601DateFormatter+Full.swift @@ -0,0 +1,17 @@ +// +// ISO8601DateFormatter+Full.swift +// stellarsdk +// +// Created by Christian Rogobete on 14.01.25. +// Copyright © 2025 Soneso. All rights reserved. +// + +import Foundation + +extension ISO8601DateFormatter { + public static let full: ISO8601DateFormatter = { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = [.withFullDate, .withFullTime, .withTimeZone, .withFractionalSeconds] + return formatter + }() +} diff --git a/stellarsdk/stellarsdk/interactive/responses/Sep24TransactionResponse.swift b/stellarsdk/stellarsdk/interactive/responses/Sep24TransactionResponse.swift index 1db3d08e..b78a538b 100644 --- a/stellarsdk/stellarsdk/interactive/responses/Sep24TransactionResponse.swift +++ b/stellarsdk/stellarsdk/interactive/responses/Sep24TransactionResponse.swift @@ -74,7 +74,7 @@ public struct Sep24Transaction: Decodable { /// Amount sent by anchor to user at end of transaction as a string with up to 7 decimals. /// Excludes amount converted to XLM to fund account and any external fees. - public var amountOut:String + public var amountOut:String? /// (optional) The asset delivered or to be delivered to the user. Must be present if the deposit/withdraw was made using non-equivalent assets. /// The value must be in SEP-38 Asset Identification Format. @@ -84,7 +84,7 @@ public struct Sep24Transaction: Decodable { public var amountOutAsset:String? /// Amount of fee charged by anchor - public var amountFee:String + public var amountFee:String? /// (optional) The asset in which fees are calculated in. Must be present if the deposit/withdraw was made using non-equivalent assets. /// The value must be in SEP-38 Asset Identification Format. @@ -210,17 +210,42 @@ public struct Sep24Transaction: Decodable { statusEta = try values.decodeIfPresent(Int.self, forKey: .statusEta) kycVerified = try values.decodeIfPresent(Bool.self, forKey: .kycVerified) moreInfoUrl = try values.decodeIfPresent(String.self, forKey: .moreInfoUrl) - amountIn = try values.decode(String.self, forKey: .amountIn) + amountIn = try values.decodeIfPresent(String.self, forKey: .amountIn) amountInAsset = try values.decodeIfPresent(String.self, forKey: .amountInAsset) - amountOut = try values.decode(String.self, forKey: .amountOut) + amountOut = try values.decodeIfPresent(String.self, forKey: .amountOut) amountOutAsset = try values.decodeIfPresent(String.self, forKey: .amountOutAsset) - amountFee = try values.decode(String.self, forKey: .amountFee) + amountFee = try values.decodeIfPresent(String.self, forKey: .amountFee) amountFeeAsset = try values.decodeIfPresent(String.self, forKey: .amountFeeAsset) quoteId = try values.decodeIfPresent(String.self, forKey: .quoteId) - startedAt = try values.decode(Date.self, forKey: .startedAt) - completedAt = try values.decodeIfPresent(Date.self, forKey: .completedAt) - updatedAt = try values.decodeIfPresent(Date.self, forKey: .updatedAt) - userActionRequiredBy = try values.decodeIfPresent(Date.self, forKey: .userActionRequiredBy) + + let startedAtStr = try values.decode(String.self, forKey: .startedAt) + if let startedAtDate = ISO8601DateFormatter.full.date(from: startedAtStr) { + startedAt = startedAtDate + } else { + startedAt = try values.decode(Date.self, forKey: .startedAt) + } + + if let completedAtStr = try values.decodeIfPresent(String.self, forKey: .completedAt), + let completedAtDate = ISO8601DateFormatter.full.date(from: completedAtStr) { + completedAt = completedAtDate + } else { + completedAt = try values.decodeIfPresent(Date.self, forKey: .completedAt) + } + + if let updatedAtStr = try values.decodeIfPresent(String.self, forKey: .updatedAt), + let updatedAtDate = ISO8601DateFormatter.full.date(from: updatedAtStr) { + updatedAt = updatedAtDate + } else { + updatedAt = try values.decodeIfPresent(Date.self, forKey: .updatedAt) + } + + if let userActionRequiredByStr = try values.decodeIfPresent(String.self, forKey: .userActionRequiredBy), + let userActionRequiredByDate = ISO8601DateFormatter.full.date(from: userActionRequiredByStr) { + userActionRequiredBy = userActionRequiredByDate + } else { + userActionRequiredBy = try values.decodeIfPresent(Date.self, forKey: .userActionRequiredBy) + } + stellarTransactionId = try values.decodeIfPresent(String.self, forKey: .stellarTransactionId) externalTransactionId = try values.decodeIfPresent(String.self, forKey: .externalTransactionId) message = try values.decodeIfPresent(String.self, forKey: .message) diff --git a/stellarsdk/stellarsdk/kyc/responses/CustomerFileResponse.swift b/stellarsdk/stellarsdk/kyc/responses/CustomerFileResponse.swift index 63a0cdca..26969ba7 100644 --- a/stellarsdk/stellarsdk/kyc/responses/CustomerFileResponse.swift +++ b/stellarsdk/stellarsdk/kyc/responses/CustomerFileResponse.swift @@ -44,7 +44,12 @@ public struct CustomerFileResponse: Decodable { fileId = try values.decode(String.self, forKey: .fileId) contentType = try values.decode(String.self, forKey: .contentType) size = try values.decode(Int.self, forKey: .size) - expiresAt = try values.decodeIfPresent(Date.self, forKey: .expiresAt) + if let expiresAtStr = try values.decodeIfPresent(String.self, forKey: .expiresAt), + let expiresAtDate = ISO8601DateFormatter.full.date(from: expiresAtStr) { + expiresAt = expiresAtDate + } else { + expiresAt = try values.decodeIfPresent(Date.self, forKey: .expiresAt) + } customerId = try values.decodeIfPresent(String.self, forKey: .customerId) } } diff --git a/stellarsdk/stellarsdk/quote/responses/Sep38Responses.swift b/stellarsdk/stellarsdk/quote/responses/Sep38Responses.swift index a5d686bd..4bb0332c 100644 --- a/stellarsdk/stellarsdk/quote/responses/Sep38Responses.swift +++ b/stellarsdk/stellarsdk/quote/responses/Sep38Responses.swift @@ -81,7 +81,12 @@ public struct Sep38QuoteResponse: Decodable { public init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) id = try values.decode(String.self, forKey: .id) - expiresAt = try values.decode(Date.self, forKey: .expiresAt) + let expiresAtStr = try values.decode(String.self, forKey: .expiresAt) + if let expiresAtDate = ISO8601DateFormatter.full.date(from: expiresAtStr) { + expiresAt = expiresAtDate + } else { + expiresAt = try values.decode(Date.self, forKey: .expiresAt) + } totalPrice = try values.decode(String.self, forKey: .totalPrice) price = try values.decode(String.self, forKey: .price) sellAsset = try values.decode(String.self, forKey: .sellAsset) diff --git a/stellarsdk/stellarsdk/transfer_server_protocol/responses/AnchorTransactionsResponse.swift b/stellarsdk/stellarsdk/transfer_server_protocol/responses/AnchorTransactionsResponse.swift index 9623e632..2d9bcea7 100644 --- a/stellarsdk/stellarsdk/transfer_server_protocol/responses/AnchorTransactionsResponse.swift +++ b/stellarsdk/stellarsdk/transfer_server_protocol/responses/AnchorTransactionsResponse.swift @@ -270,10 +270,35 @@ public struct AnchorTransaction: Decodable { withdrawAnchorAccount = try values.decodeIfPresent(String.self, forKey: .withdrawAnchorAccount) withdrawMemo = try values.decodeIfPresent(String.self, forKey: .withdrawMemo) withdrawMemoType = try values.decodeIfPresent(String.self, forKey: .withdrawMemoType) - startedAt = try values.decodeIfPresent(Date.self, forKey: .startedAt) - updatedAt = try values.decodeIfPresent(Date.self, forKey: .updatedAt) - completedAt = try values.decodeIfPresent(Date.self, forKey: .completedAt) - userActionRequiredBy = try values.decodeIfPresent(Date.self, forKey: .userActionRequiredBy) + + let startedAtStr = try values.decode(String.self, forKey: .startedAt) + if let startedAtDate = ISO8601DateFormatter.full.date(from: startedAtStr) { + startedAt = startedAtDate + } else { + startedAt = try values.decode(Date.self, forKey: .startedAt) + } + + if let completedAtStr = try values.decodeIfPresent(String.self, forKey: .completedAt), + let completedAtDate = ISO8601DateFormatter.full.date(from: completedAtStr) { + completedAt = completedAtDate + } else { + completedAt = try values.decodeIfPresent(Date.self, forKey: .completedAt) + } + + if let updatedAtStr = try values.decodeIfPresent(String.self, forKey: .updatedAt), + let updatedAtDate = ISO8601DateFormatter.full.date(from: updatedAtStr) { + updatedAt = updatedAtDate + } else { + updatedAt = try values.decodeIfPresent(Date.self, forKey: .updatedAt) + } + + if let userActionRequiredByStr = try values.decodeIfPresent(String.self, forKey: .userActionRequiredBy), + let userActionRequiredByDate = ISO8601DateFormatter.full.date(from: userActionRequiredByStr) { + userActionRequiredBy = userActionRequiredByDate + } else { + userActionRequiredBy = try values.decodeIfPresent(Date.self, forKey: .userActionRequiredBy) + } + stellarTransactionId = try values.decodeIfPresent(String.self, forKey: .stellarTransactionId) externalTransactionId = try values.decodeIfPresent(String.self, forKey: .externalTransactionId) message = try values.decodeIfPresent(String.self, forKey: .message) diff --git a/stellarsdk/stellarsdkTests/interactive/InteractiveServiceTestCase.swift b/stellarsdk/stellarsdkTests/interactive/InteractiveServiceTestCase.swift index 44848905..4ee848c1 100644 --- a/stellarsdk/stellarsdkTests/interactive/InteractiveServiceTestCase.swift +++ b/stellarsdk/stellarsdkTests/interactive/InteractiveServiceTestCase.swift @@ -186,9 +186,9 @@ class InteractiveServiceTestCase: XCTestCase { XCTAssertEqual("510", tx.amountIn) XCTAssertEqual("490", tx.amountOut) XCTAssertEqual("5", tx.amountFee) - XCTAssertEqual("2017-03-20T17:00:02Z", tx.startedAt.ISO8601Format()) - XCTAssertEqual("2017-03-20T17:09:58Z", tx.completedAt!.ISO8601Format()) - XCTAssertEqual("2017-03-20T17:09:58Z", tx.updatedAt!.ISO8601Format()) + XCTAssertEqual("2025-01-14T14:22:06Z", tx.startedAt.ISO8601Format()) + XCTAssertEqual("2025-01-14T14:22:07Z", tx.updatedAt!.ISO8601Format()) + XCTAssertEqual("2025-01-14T14:22:08Z", tx.completedAt!.ISO8601Format()) XCTAssertEqual("https://youranchor.com/tx/242523523", tx.moreInfoUrl) XCTAssertNil(tx.claimableBalanceId) XCTAssertNil(tx.refunded) diff --git a/stellarsdk/stellarsdkTests/interactive/Sep24TransactionResponseMock.swift b/stellarsdk/stellarsdkTests/interactive/Sep24TransactionResponseMock.swift index d13876cd..f60a1748 100644 --- a/stellarsdk/stellarsdkTests/interactive/Sep24TransactionResponseMock.swift +++ b/stellarsdk/stellarsdkTests/interactive/Sep24TransactionResponseMock.swift @@ -36,9 +36,9 @@ class Sep24TransactionResponseMock: ResponsesMock { "amount_in": "510", "amount_out": "490", "amount_fee": "5", - "started_at": "2017-03-20T17:00:02Z", - "completed_at": "2017-03-20T17:09:58Z", - "updated_at": "2017-03-20T17:09:58Z", + "started_at": "2025-01-14T14:22:06.391779Z", + "completed_at": "2025-01-14T14:22:08.491Z", + "updated_at": "2025-01-14T14:22:07Z", "more_info_url": "https://youranchor.com/tx/242523523", "stellar_transaction_id": "17a670bc424ff5ce3b386dbfaae9990b66a2a37b4fbe51547e8794962a3f9e6a", "external_transaction_id": "1941491", diff --git a/stellarsdk/stellarsdkTests/soroban/SorobanAuthTest.swift b/stellarsdk/stellarsdkTests/soroban/SorobanAuthTest.swift index bff9d4e2..3bb1997f 100644 --- a/stellarsdk/stellarsdkTests/soroban/SorobanAuthTest.swift +++ b/stellarsdk/stellarsdkTests/soroban/SorobanAuthTest.swift @@ -12,9 +12,9 @@ import stellarsdk class SorobanAuthTest: XCTestCase { - let sorobanServer = SorobanServer(endpoint: "https://rpc-futurenet.stellar.org") // SorobanServer(endpoint: "https://soroban-testnet.stellar.org") - let sdk = StellarSDK.futureNet() // StellarSDK.testNet() - let network = Network.futurenet // Network.testnet + let sorobanServer = SorobanServer(endpoint: "https://soroban-testnet.stellar.org") // SorobanServer(endpoint: "https://rpc-futurenet.stellar.org") + let sdk = StellarSDK.testNet() // StellarSDK.futureNet() + let network = Network.testnet // Network.futurenet var invokerKeyPair = try! KeyPair.generateRandomKeyPair() var senderKeyPair = try! KeyPair.generateRandomKeyPair() var installTransactionId:String? @@ -34,8 +34,8 @@ class SorobanAuthTest: XCTestCase { let invokerId = invokerKeyPair.accountId let senderId = senderKeyPair.accountId - //var responseEnum = await sdk.accounts.createTestAccount(accountId: invokerId) - var responseEnum = await sdk.accounts.createFutureNetTestAccount(accountId: invokerId) + var responseEnum = await sdk.accounts.createTestAccount(accountId: invokerId) + //var responseEnum = await sdk.accounts.createFutureNetTestAccount(accountId: invokerId) switch responseEnum { case .success(_): break @@ -44,8 +44,8 @@ class SorobanAuthTest: XCTestCase { XCTFail("could not create invoker account: \(invokerId)") } - responseEnum = await sdk.accounts.createFutureNetTestAccount(accountId: senderId) - // responseEnum = await sdk.accounts.createTestAccount(accountId: senderId) + //responseEnum = await sdk.accounts.createFutureNetTestAccount(accountId: senderId) + responseEnum = await sdk.accounts.createTestAccount(accountId: senderId) switch responseEnum { case .success(_): break diff --git a/stellarsdk/stellarsdkTests/soroban/SorobanEventsTest.swift b/stellarsdk/stellarsdkTests/soroban/SorobanEventsTest.swift index 14a8075e..f9fef35d 100644 --- a/stellarsdk/stellarsdkTests/soroban/SorobanEventsTest.swift +++ b/stellarsdk/stellarsdkTests/soroban/SorobanEventsTest.swift @@ -45,6 +45,7 @@ class SorobanEventsTest: XCTestCase { func testAll() async { await refreshSubmitterAccount() + await restoreContractCodeFootprint(name: "soroban_events_contract") await uploadContractWasm(name: "soroban_events_contract") await refreshSubmitterAccount() @@ -293,4 +294,92 @@ class SorobanEventsTest: XCTestCase { print(message) } } + + func restoreContractCodeFootprint(name:String) async { + let bundle = Bundle(for: type(of: self)) + guard let path = bundle.path(forResource: name, ofType: "wasm") else { + // File not found + XCTFail() + return + } + let contractCode = FileManager.default.contents(atPath: path) + let uploadOperation = try! InvokeHostFunctionOperation.forUploadingContractWasm(contractCode: contractCode!) + + var transaction = try! Transaction(sourceAccount: submitterAccount!, + operations: [uploadOperation], memo: Memo.none) + + var simulateTxResponse:SimulateTransactionResponse? = nil + var simulateTxRequest = SimulateTransactionRequest(transaction: transaction); + var simulateTxResonseEnum = await sorobanServer.simulateTransaction(simulateTxRequest: simulateTxRequest) + switch simulateTxResonseEnum { + case .success(let response): + simulateTxResponse = response + case .failure(let error): + self.printError(error: error) + XCTFail() + } + + XCTAssertNotNil(simulateTxResponse) + XCTAssertNotNil(simulateTxResponse!.transactionData) + XCTAssertNotNil(simulateTxResponse!.minResourceFee) + + let restoreFootprintOperation = RestoreFootprintOperation() + + // every time we build a transaction with the source account it increments the sequence number + // so we decrement it now so we do not have to reload it + self.submitterAccount!.decrementSequenceNumber() + transaction = try! Transaction(sourceAccount: self.submitterAccount!, + operations: [restoreFootprintOperation], memo: Memo.none) + + var transactionData = simulateTxResponse!.transactionData! + transactionData.resources.footprint.readWrite.append(contentsOf:transactionData.resources.footprint.readOnly) + transactionData.resources.footprint.readOnly = [] // readonly must be empty + transaction.setSorobanTransactionData(data: transactionData) + transaction.addResourceFee(resourceFee: simulateTxResponse!.minResourceFee!) + + // simulate first to obtain the transaction data + resource fee + simulateTxRequest = SimulateTransactionRequest(transaction: transaction); + simulateTxResonseEnum = await sorobanServer.simulateTransaction(simulateTxRequest: simulateTxRequest) + switch simulateTxResonseEnum { + case .success(let response): + simulateTxResponse = response + case .failure(let error): + self.printError(error: error) + XCTFail() + } + XCTAssertNotNil(simulateTxResponse) + XCTAssertNotNil(simulateTxResponse!.transactionData) + XCTAssertNotNil(simulateTxResponse!.minResourceFee) + + transactionData = simulateTxResponse!.transactionData! + transactionData.resources.footprint.readWrite.append(contentsOf:transactionData.resources.footprint.readOnly) + transactionData.resources.footprint.readOnly = [] + transaction.setSorobanTransactionData(data: transactionData) + let ressourceFee = simulateTxResponse!.minResourceFee! + 5000 + transaction.addResourceFee(resourceFee: ressourceFee) + + try! transaction.sign(keyPair: self.submitterKeyPair, network: self.network) + + // check encoding and decoding + let enveloperXdr = try! transaction.encodedEnvelope(); + XCTAssertEqual(enveloperXdr, try! Transaction(envelopeXdr: enveloperXdr).encodedEnvelope()) + + let sendTxResponseEnum = await sorobanServer.sendTransaction(transaction: transaction) + switch sendTxResponseEnum { + case .success(let response): + XCTAssert(SendTransactionResponse.STATUS_ERROR != response.status) + try! await Task.sleep(nanoseconds: UInt64(10 * Double(NSEC_PER_SEC))) + let txResultEnum = await sorobanServer.getTransaction(transactionHash: response.transactionId) + switch txResultEnum { + case .success(let statusResponse): + XCTAssertEqual(GetTransactionResponse.STATUS_SUCCESS, statusResponse.status) + case .failure(let error): + self.printError(error: error) + XCTFail() + } + case .failure(let error): + self.printError(error: error) + XCTFail() + } + } }