From d06d1d11b0941d35295b3e8e9f370ead04442c0c Mon Sep 17 00:00:00 2001 From: nerzh Date: Mon, 22 May 2023 23:50:57 +0200 Subject: [PATCH] update 1.42.1 --- .../Sources/ApiParser/CodeGenerator.swift | 6 +- README.md | 2 +- .../EverscaleClientSwift/Client/Client.swift | 4 + .../Client/ClientTypes.swift | 4 +- .../EverscaleClientSwift/Net/NetTypes.swift | 1 + .../Processing/Processing.swift | 205 ++++++++++++++++++ .../Processing/ProcessingTypes.swift | 193 +++++++++++++++++ 7 files changed, 409 insertions(+), 6 deletions(-) diff --git a/ApiParser/Sources/ApiParser/CodeGenerator.swift b/ApiParser/Sources/ApiParser/CodeGenerator.swift index 52fd000..777d142 100644 --- a/ApiParser/Sources/ApiParser/CodeGenerator.swift +++ b/ApiParser/Sources/ApiParser/CodeGenerator.swift @@ -317,13 +317,13 @@ extension CodeGenerator { \n public init(_ error: Error) { self.code = 0 self.message = error.localizedDescription - self.data = ([:] as! [String: Any]).toAnyValue() + self.data = [String: Any]().toAnyValue() } public init(_ message: String) { self.code = 0 self.message = message - self.data = ([:] as! [String: Any]).toAnyValue() + self.data = [String: Any]().toAnyValue() }\n """ result.append(customInit) @@ -334,7 +334,7 @@ extension CodeGenerator { result.append("\(property.name): \(property.type) = nil") } else { if property.name == "data" { - result.append("\(property.name): \(property.type) = ([:] as! [String: Any]).toAnyValue()") + result.append("\(property.name): \(property.type) = [String: Any]().toAnyValue()") } else { result.append("\(property.name): \(property.type)") } diff --git a/README.md b/README.md index 3eb2bd4..26bd433 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@

[![SPM](https://img.shields.io/badge/swift-package%20manager-green)](https://swift.org/package-manager/) -[![SPM](https://img.shields.io/badge/SDK%20VERSION-1.41.1-orange)](https://github.com/tonlabs/ever-sdk) +[![SPM](https://img.shields.io/badge/SDK%20VERSION-1.42.1-orange)](https://github.com/tonlabs/ever-sdk) Swift is a strongly typed language that has long been used not only for iOS development. Apple is actively promoting it to new platforms and today it can be used for almost any task. Thanks to this, this implementation provides the work of TVM (toncoin, everscale, venom, gosh) SDK on many platforms at once, including the native one for mobile phones. Let me remind you that swift can also be built for android. diff --git a/Sources/EverscaleClientSwift/Client/Client.swift b/Sources/EverscaleClientSwift/Client/Client.swift index a1ae4cd..2142480 100644 --- a/Sources/EverscaleClientSwift/Client/Client.swift +++ b/Sources/EverscaleClientSwift/Client/Client.swift @@ -201,4 +201,8 @@ public final class TSDKClientModule { } } } + + deinit { + print("Client DEINIT !") + } } diff --git a/Sources/EverscaleClientSwift/Client/ClientTypes.swift b/Sources/EverscaleClientSwift/Client/ClientTypes.swift index 7549ef0..b3c2cd8 100644 --- a/Sources/EverscaleClientSwift/Client/ClientTypes.swift +++ b/Sources/EverscaleClientSwift/Client/ClientTypes.swift @@ -60,7 +60,7 @@ public struct TSDKClientError: Codable, LocalizedError { public var failureReason: String? { self.message } public var recoverySuggestion: String? { self.message } public var helpAnchor: String? { self.message } - public var data: AnyValue = [String: Any]().toAnyValue() + public var data: AnyValue = ([:] as! [String: Any]).toAnyValue() public init(_ error: Error) { self.code = 0 @@ -151,7 +151,7 @@ public struct TSDKNetworkConfig: Codable { public var queries_protocol: TSDKNetworkQueriesProtocol? /// UNSTABLE. /// First REMP status awaiting timeout. If no status received during the timeout than fallback transaction scenario is activated. - /// Must be specified in milliseconds. Default is 1000 (1 sec). + /// Must be specified in milliseconds. Default is 1 (1 ms) in order to start fallback scenariotogether with REMP statuses processing while REMP is not properly tuned yet. public var first_remp_status_timeout: UInt32? /// UNSTABLE. /// Subsequent REMP status awaiting timeout. If no status received during the timeout than fallback transaction scenario is activated. diff --git a/Sources/EverscaleClientSwift/Net/NetTypes.swift b/Sources/EverscaleClientSwift/Net/NetTypes.swift index dc8a4d4..77e532a 100644 --- a/Sources/EverscaleClientSwift/Net/NetTypes.swift +++ b/Sources/EverscaleClientSwift/Net/NetTypes.swift @@ -20,6 +20,7 @@ public enum TSDKNetErrorCode: Int, Codable { case Unauthorized = 615 case QueryTransactionTreeTimeout = 616 case GraphqlConnectionError = 617 + case WrongWebscoketProtocolSequence = 618 } public enum TSDKSortDirection: String, Codable { diff --git a/Sources/EverscaleClientSwift/Processing/Processing.swift b/Sources/EverscaleClientSwift/Processing/Processing.swift index 9213405..5a0eead 100644 --- a/Sources/EverscaleClientSwift/Processing/Processing.swift +++ b/Sources/EverscaleClientSwift/Processing/Processing.swift @@ -7,6 +7,211 @@ public final class TSDKProcessingModule { self.binding = binding } + /// Starts monitoring for the processing results of the specified messages. + /// Message monitor performs background monitoring for a message processing resultsfor the specified set of messages. + /// Message monitor can serve several isolated monitoring queues. + /// Each monitor queue has a unique application defined identifier (or name) usedto separate several queue's. + /// There are two important lists inside of the monitoring queue: + /// - unresolved messages: contains messages requested by the application for monitoring and not yet resolved; + /// - resolved results: contains resolved processing results for monitored messages. + /// Each monitoring queue tracks own unresolved and resolved lists. + /// Application can add more messages to the monitoring queue at any time. + /// Message monitor accumulates resolved results. + /// Application should fetch this results with `fetchNextMonitorResults` function. + /// When both unresolved and resolved lists becomes empty, monitor stops any background activityand frees all allocated internal memory. + /// If monitoring queue with specified name already exists then messages will be addedto the unresolved list. + /// If monitoring queue with specified name does not exist then monitoring queue will be createdwith specified unresolved messages. + public func monitor_messages(_ payload: TSDKParamsOfMonitorMessages, _ handler: @escaping (TSDKBindingResponse) throws -> Void + ) throws { + let method: String = "monitor_messages" + try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + try handler(response) + } + } + + /// Starts monitoring for the processing results of the specified messages. + /// Message monitor performs background monitoring for a message processing resultsfor the specified set of messages. + /// Message monitor can serve several isolated monitoring queues. + /// Each monitor queue has a unique application defined identifier (or name) usedto separate several queue's. + /// There are two important lists inside of the monitoring queue: + /// - unresolved messages: contains messages requested by the application for monitoring and not yet resolved; + /// - resolved results: contains resolved processing results for monitored messages. + /// Each monitoring queue tracks own unresolved and resolved lists. + /// Application can add more messages to the monitoring queue at any time. + /// Message monitor accumulates resolved results. + /// Application should fetch this results with `fetchNextMonitorResults` function. + /// When both unresolved and resolved lists becomes empty, monitor stops any background activityand frees all allocated internal memory. + /// If monitoring queue with specified name already exists then messages will be addedto the unresolved list. + /// If monitoring queue with specified name does not exist then monitoring queue will be createdwith specified unresolved messages. + @available(iOS 13, *) + @available(macOS 12, *) + public func monitor_messages(_ payload: TSDKParamsOfMonitorMessages) async throws -> TSDKNoneResult { + try await withCheckedThrowingContinuation { continuation in + do { + let method: String = "monitor_messages" + try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + if let error = response.error { + continuation.resume(throwing: error) + } else if let result = response.result { + continuation.resume(returning: result) + } else { + continuation.resume(throwing: TSDKClientError("Nothing for return")) + } + } + } catch { + continuation.resume(throwing: error) + } + } + } + + /// Returns summary information about current state of the specified monitoring queue. + public func get_monitor_info(_ payload: TSDKParamsOfGetMonitorInfo, _ handler: @escaping (TSDKBindingResponse) throws -> Void + ) throws { + let method: String = "get_monitor_info" + try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + try handler(response) + } + } + + /// Returns summary information about current state of the specified monitoring queue. + @available(iOS 13, *) + @available(macOS 12, *) + public func get_monitor_info(_ payload: TSDKParamsOfGetMonitorInfo) async throws -> TSDKMonitoringQueueInfo { + try await withCheckedThrowingContinuation { continuation in + do { + let method: String = "get_monitor_info" + try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + if let error = response.error { + continuation.resume(throwing: error) + } else if let result = response.result { + continuation.resume(returning: result) + } else { + continuation.resume(throwing: TSDKClientError("Nothing for return")) + } + } + } catch { + continuation.resume(throwing: error) + } + } + } + + /// Fetches next resolved results from the specified monitoring queue. + /// Results and waiting options are depends on the `wait` parameter. + /// All returned results will be removed from the queue's resolved list. + public func fetch_next_monitor_results(_ payload: TSDKParamsOfFetchNextMonitorResults, _ handler: @escaping (TSDKBindingResponse) throws -> Void + ) throws { + let method: String = "fetch_next_monitor_results" + try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + try handler(response) + } + } + + /// Fetches next resolved results from the specified monitoring queue. + /// Results and waiting options are depends on the `wait` parameter. + /// All returned results will be removed from the queue's resolved list. + @available(iOS 13, *) + @available(macOS 12, *) + public func fetch_next_monitor_results(_ payload: TSDKParamsOfFetchNextMonitorResults) async throws -> TSDKResultOfFetchNextMonitorResults { + try await withCheckedThrowingContinuation { continuation in + do { + let method: String = "fetch_next_monitor_results" + try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + if let error = response.error { + continuation.resume(throwing: error) + } else if let result = response.result { + continuation.resume(returning: result) + } else { + continuation.resume(throwing: TSDKClientError("Nothing for return")) + } + } + } catch { + continuation.resume(throwing: error) + } + } + } + + /// Cancels all background activity and releases all allocated system resources for the specified monitoring queue. + public func cancel_monitor(_ payload: TSDKParamsOfCancelMonitor, _ handler: @escaping (TSDKBindingResponse) throws -> Void + ) throws { + let method: String = "cancel_monitor" + try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + try handler(response) + } + } + + /// Cancels all background activity and releases all allocated system resources for the specified monitoring queue. + @available(iOS 13, *) + @available(macOS 12, *) + public func cancel_monitor(_ payload: TSDKParamsOfCancelMonitor) async throws -> TSDKNoneResult { + try await withCheckedThrowingContinuation { continuation in + do { + let method: String = "cancel_monitor" + try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + if let error = response.error { + continuation.resume(throwing: error) + } else if let result = response.result { + continuation.resume(returning: result) + } else { + continuation.resume(throwing: TSDKClientError("Nothing for return")) + } + } + } catch { + continuation.resume(throwing: error) + } + } + } + + /// Sends specified messages to the blockchain. + public func send_messages(_ payload: TSDKParamsOfSendMessages, _ handler: @escaping (TSDKBindingResponse) throws -> Void + ) throws { + let method: String = "send_messages" + try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + try handler(response) + } + } + + /// Sends specified messages to the blockchain. + @available(iOS 13, *) + @available(macOS 12, *) + public func send_messages(_ payload: TSDKParamsOfSendMessages) async throws -> TSDKResultOfSendMessages { + try await withCheckedThrowingContinuation { continuation in + do { + let method: String = "send_messages" + try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in + var response: TSDKBindingResponse = .init() + response.update(requestId, params, responseType, finished) + if let error = response.error { + continuation.resume(throwing: error) + } else if let result = response.result { + continuation.resume(returning: result) + } else { + continuation.resume(throwing: TSDKClientError("Nothing for return")) + } + } + } catch { + continuation.resume(throwing: error) + } + } + } + /// Sends message to the network /// Sends message to the network and returns the last generated shard block of the destination accountbefore the message was sent. It will be required later for message processing. public func send_message(_ payload: TSDKParamsOfSendMessage, _ handler: @escaping (TSDKBindingResponse) throws -> Void diff --git a/Sources/EverscaleClientSwift/Processing/ProcessingTypes.swift b/Sources/EverscaleClientSwift/Processing/ProcessingTypes.swift index 4b7fca8..b77a96b 100644 --- a/Sources/EverscaleClientSwift/Processing/ProcessingTypes.swift +++ b/Sources/EverscaleClientSwift/Processing/ProcessingTypes.swift @@ -37,6 +37,23 @@ public enum TSDKProcessingEventEnumTypes: String, Codable { case RempError = "RempError" } +public enum TSDKMonitorFetchWaitMode: String, Codable { + case AtLeastOne = "AtLeastOne" + case All = "All" + case NoWait = "NoWait" +} + +public enum TSDKMonitoredMessageEnumTypes: String, Codable { + case Boc = "Boc" + case HashAddress = "HashAddress" +} + +public enum TSDKMessageMonitoringStatus: String, Codable { + case Finalized = "Finalized" + case Timeout = "Timeout" + case Reserved = "Reserved" +} + public struct TSDKProcessingEvent: Codable { public var type: TSDKProcessingEventEnumTypes public var message_id: String? @@ -92,6 +109,182 @@ public struct TSDKDecodedOutput: Codable { } } +public struct TSDKMessageMonitoringTransactionCompute: Codable { + /// Compute phase exit code. + public var exit_code: Int32 + + public init(exit_code: Int32) { + self.exit_code = exit_code + } +} + +public struct TSDKMessageMonitoringTransaction: Codable { + /// Hash of the transaction. Present if transaction was included into the blocks. When then transaction was emulated this field will be missing. + public var hash: String? + /// Aborted field of the transaction. + public var aborted: Bool + /// Optional information about the compute phase of the transaction. + public var compute: TSDKMessageMonitoringTransactionCompute? + + public init(hash: String? = nil, aborted: Bool, compute: TSDKMessageMonitoringTransactionCompute? = nil) { + self.hash = hash + self.aborted = aborted + self.compute = compute + } +} + +public struct TSDKMessageMonitoringParams: Codable { + /// Monitored message identification. Can be provided as a message's BOC or (hash, address) pair. BOC is a preferable way because it helps to determine possible error reason (using TVM execution of the message). + public var message: TSDKMonitoredMessage + /// Block time Must be specified as a UNIX timestamp in seconds + public var wait_until: UInt32 + /// User defined data associated with this message. Helps to identify this message when user received `MessageMonitoringResult`. + public var user_data: AnyValue? + + public init(message: TSDKMonitoredMessage, wait_until: UInt32, user_data: AnyValue? = nil) { + self.message = message + self.wait_until = wait_until + self.user_data = user_data + } +} + +public struct TSDKMessageMonitoringResult: Codable { + /// Hash of the message. + public var hash: String + /// Processing status. + public var status: TSDKMessageMonitoringStatus + /// In case of `Finalized` the transaction is extracted from the block. In case of `Timeout` the transaction is emulated using the last known account state. + public var transaction: TSDKMessageMonitoringTransaction? + /// In case of `Timeout` contains possible error reason. + public var error: String? + /// User defined data related to this message. This is the same value as passed before with `MessageMonitoringParams` or `SendMessageParams`. + public var user_data: AnyValue? + + public init(hash: String, status: TSDKMessageMonitoringStatus, transaction: TSDKMessageMonitoringTransaction? = nil, error: String? = nil, user_data: AnyValue? = nil) { + self.hash = hash + self.status = status + self.transaction = transaction + self.error = error + self.user_data = user_data + } +} + +public struct TSDKMonitoredMessage: Codable { + public var type: TSDKMonitoredMessageEnumTypes + public var boc: String? + /// Hash of the message. + public var hash: String? + /// Destination address of the message. + public var address: String? + + public init(type: TSDKMonitoredMessageEnumTypes, boc: String? = nil, hash: String? = nil, address: String? = nil) { + self.type = type + self.boc = boc + self.hash = hash + self.address = address + } +} + +public struct TSDKMessageSendingParams: Codable { + /// BOC of the message, that must be sent to the blockchain. + public var boc: String + /// Expiration time of the message. Must be specified as a UNIX timestamp in seconds. + public var wait_until: UInt32 + /// User defined data associated with this message. Helps to identify this message when user received `MessageMonitoringResult`. + public var user_data: AnyValue? + + public init(boc: String, wait_until: UInt32, user_data: AnyValue? = nil) { + self.boc = boc + self.wait_until = wait_until + self.user_data = user_data + } +} + +public struct TSDKParamsOfMonitorMessages: Codable { + /// Name of the monitoring queue. + public var queue: String + /// Messages to start monitoring for. + public var messages: [TSDKMessageMonitoringParams] + + public init(queue: String, messages: [TSDKMessageMonitoringParams]) { + self.queue = queue + self.messages = messages + } +} + +public struct TSDKParamsOfGetMonitorInfo: Codable { + /// Name of the monitoring queue. + public var queue: String + + public init(queue: String) { + self.queue = queue + } +} + +public struct TSDKMonitoringQueueInfo: Codable { + /// Count of the unresolved messages. + public var unresolved: UInt32 + /// Count of resolved results. + public var resolved: UInt32 + + public init(unresolved: UInt32, resolved: UInt32) { + self.unresolved = unresolved + self.resolved = resolved + } +} + +public struct TSDKParamsOfFetchNextMonitorResults: Codable { + /// Name of the monitoring queue. + public var queue: String + /// Wait mode. + /// Default is `NO_WAIT`. + public var wait_mode: TSDKMonitorFetchWaitMode? + + public init(queue: String, wait_mode: TSDKMonitorFetchWaitMode? = nil) { + self.queue = queue + self.wait_mode = wait_mode + } +} + +public struct TSDKResultOfFetchNextMonitorResults: Codable { + /// List of the resolved results. + public var results: [TSDKMessageMonitoringResult] + + public init(results: [TSDKMessageMonitoringResult]) { + self.results = results + } +} + +public struct TSDKParamsOfCancelMonitor: Codable { + /// Name of the monitoring queue. + public var queue: String + + public init(queue: String) { + self.queue = queue + } +} + +public struct TSDKParamsOfSendMessages: Codable { + /// Messages that must be sent to the blockchain. + public var messages: [TSDKMessageSendingParams] + /// Optional message monitor queue that starts monitoring for the processing results for sent messages. + public var monitor_queue: String? + + public init(messages: [TSDKMessageSendingParams], monitor_queue: String? = nil) { + self.messages = messages + self.monitor_queue = monitor_queue + } +} + +public struct TSDKResultOfSendMessages: Codable { + /// Messages that was sent to the blockchain for execution. + public var messages: [TSDKMessageMonitoringParams] + + public init(messages: [TSDKMessageMonitoringParams]) { + self.messages = messages + } +} + public struct TSDKParamsOfSendMessage: Codable { /// Message BOC. public var message: String