├── .gitignore
├── ApiParser
├── Package.swift
├── README.md
└── Sources
│ └── ApiParser
│ ├── CodeGenerator.swift
│ ├── Settings.swift
│ ├── TypeConverter.swift
│ └── main.swift
├── LICENSE
├── Package.swift
├── README.md
├── Sources
├── CTonSDK
│ ├── module.modulemap
│ └── shim.h
└── EverscaleClientSwift
│ ├── Abi
│ ├── Abi.swift
│ └── AbiTypes.swift
│ ├── Binding
│ ├── Binding.swift
│ ├── BindingStore.swift
│ └── BindingTypes.swift
│ ├── Boc
│ ├── Boc.swift
│ └── BocTypes.swift
│ ├── Client
│ ├── Client.swift
│ └── ClientTypes.swift
│ ├── Crypto
│ ├── Crypto.swift
│ └── CryptoTypes.swift
│ ├── Debot
│ ├── Debot.swift
│ └── DebotTypes.swift
│ ├── Extensions
│ ├── FileReader.swift
│ ├── Helpers.swift
│ └── SimpleEnv.swift
│ ├── Net
│ ├── Net.swift
│ └── NetTypes.swift
│ ├── Processing
│ ├── Processing.swift
│ └── ProcessingTypes.swift
│ ├── Proofs
│ ├── Proofs.swift
│ └── ProofsTypes.swift
│ ├── Tvm
│ ├── Tvm.swift
│ └── TvmTypes.swift
│ └── Utils
│ ├── Utils.swift
│ └── UtilsTypes.swift
├── Tests
├── EverscaleClientSwiftTests
│ ├── AbiTests.swift
│ ├── BindingTests.swift
│ ├── BocTests.swift
│ ├── ClientTests.swift
│ ├── CryptoTests.swift
│ ├── ErrorsTests.swift
│ ├── Fixtures
│ │ └── abi
│ │ │ ├── Events.abi.json
│ │ │ ├── Events.tvc
│ │ │ ├── Giver.abi.json
│ │ │ ├── GiverNodeSE.abi.json
│ │ │ ├── GiverNodeSE_v2.abi.json
│ │ │ ├── GiverNodeSE_v2.keys.json
│ │ │ ├── GiverV2.abi.json
│ │ │ ├── GiverV2.tvc
│ │ │ ├── GiverWallet.abi.json
│ │ │ ├── Hello.abi.json
│ │ │ ├── Hello.tvc
│ │ │ ├── LimitWallet.abi.json
│ │ │ ├── LimitWallet.tvc
│ │ │ ├── Piggy.abi.json
│ │ │ ├── Piggy.tvc
│ │ │ ├── SetcodeMultisigWallet2.abi.json
│ │ │ ├── SetcodeMultisigWallet2.tvc
│ │ │ ├── Subscription.abi.json
│ │ │ ├── Subscription.tvc
│ │ │ ├── Wallet.abi.json
│ │ │ ├── Wallet.tvc
│ │ │ ├── helloDebot.abi.json
│ │ │ ├── helloDebot.png
│ │ │ ├── helloDebot.sol
│ │ │ ├── helloDebot.tvc
│ │ │ ├── tda.abi.json
│ │ │ ├── tda.tvc
│ │ │ ├── tdb.abi.json
│ │ │ ├── tdb.tvc
│ │ │ ├── testDebot.abi.json
│ │ │ ├── testDebot.tvc
│ │ │ ├── testDebot2.abi.json
│ │ │ ├── testDebot2.tvc
│ │ │ ├── testDebot3.abi.json
│ │ │ ├── testDebot3.sol
│ │ │ ├── testDebot3.tvc
│ │ │ ├── testDebot4.abi.json
│ │ │ ├── testDebot4.tvc
│ │ │ ├── testDebot5.abi.json
│ │ │ ├── testDebot5.tvc
│ │ │ ├── testDebot6.abi.json
│ │ │ ├── testDebot6.sol
│ │ │ ├── testDebot6.tvc
│ │ │ ├── testDebot7.abi.json
│ │ │ ├── testDebot7.sol
│ │ │ ├── testDebot7.tvc
│ │ │ ├── testDebot8.abi.json
│ │ │ ├── testDebot8.sol
│ │ │ ├── testDebot8.tvc
│ │ │ ├── testDebotTarget.abi.json
│ │ │ └── testDebotTarget.tvc
│ ├── Helpers.swift
│ ├── NetTests.swift
│ ├── ProcessingTests.swift
│ ├── TvmTests.swift
│ └── UtilsTests.swift
└── LinuxMain.swift
├── api_generate.sh
└── scripts
├── install_rust.sh
└── install_tonsdk.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | Packages
2 | .build
3 | xcuserdata
4 | *.xcodeproj
5 | DerivedData/
6 | .DS_Store
7 | .swiftpm
8 | db.sqlite
9 | .env*
10 | Keys/*
11 | !Keys/.gitkeep
12 | Package.resolved
13 | TON-SDK/*
14 | dependencies/*
15 | api.json
--------------------------------------------------------------------------------
/ApiParser/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:6.0
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "ApiParser",
8 | platforms: [
9 | .macOS(SupportedPlatform.MacOSVersion.v10_13)
10 | ],
11 | products: [
12 | .executable(name: "ApiParser", targets: ["ApiParser"])
13 | ],
14 | dependencies: [
15 | .package(url: "https://github.com/nerzh/swift-regular-expression.git", .upToNextMajor(from: "0.2.4")),
16 | .package(url: "https://github.com/apple/swift-argument-parser", .upToNextMinor(from: "0.4.3")),
17 | .package(url: "https://github.com/nerzh/SwiftFileUtils", .upToNextMinor(from: "1.3.0")),
18 | ],
19 | targets: [
20 | .executableTarget(
21 | name: "ApiParser",
22 | dependencies: [
23 | .product(name: "SwiftRegularExpression", package: "swift-regular-expression"),
24 | .product(name: "ArgumentParser", package: "swift-argument-parser"),
25 | .product(name: "FileUtils", package: "SwiftFileUtils"),
26 | ]),
27 | ]
28 | )
29 |
--------------------------------------------------------------------------------
/ApiParser/README.md:
--------------------------------------------------------------------------------
1 | # Api Parser For Everscale Swift Client [Swift Everscale SDK](https://github.com/nerzh/everscale-client-swift)
2 |
3 | ### Update SDK
4 |
5 | ```bash
6 | cd everscale-client-swift
7 | ```
8 | ```bash
9 | bash api_generate.sh
10 | ```
11 |
--------------------------------------------------------------------------------
/ApiParser/Sources/ApiParser/Settings.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 08.05.2021.
6 | //
7 |
8 | import Foundation
9 |
10 | let libPrefix: String = "TSDK"
11 | let libEnumPostfix: String = "EnumTypes"
12 | let defaultEnumParents: [String] = ["String", "Codable"]
13 | let defaultStructTypeParents: [String] = ["Codable"]
14 |
--------------------------------------------------------------------------------
/ApiParser/Sources/ApiParser/main.swift:
--------------------------------------------------------------------------------
1 | //
2 | // main.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 04.05.2021.
6 | //
7 |
8 | import ArgumentParser
9 | import FileUtils
10 | import Foundation
11 | import SwiftRegularExpression
12 |
13 | struct ApiParser: ParsableCommand {
14 |
15 | @Argument(help: "Path to api json file.")
16 | var pathToApiFile: String
17 |
18 | mutating func run() throws {
19 | let api = try SDKApi.init(pathToApiFile)
20 | let sdkSwiftModel = api.convertToSwift()
21 | let generator = CodeGenerator(swiftApi: sdkSwiftModel)
22 | generator.generate()
23 | try changeReadMeSDKVersion(sdkSwiftModel)
24 | }
25 |
26 | private func changeReadMeSDKVersion(_ sdkSwiftModel: SDKSwiftApi) throws {
27 | let readMePath: String = "./../README.md"
28 | let readMeURL: URL = URL(fileURLWithPath: readMePath)
29 | var fileText: String = try FileUtils.readFile(readMeURL)
30 | fileText.replaceSelf(#"VERSION-.+?-orange"#, "VERSION-\(sdkSwiftModel.version)-orange")
31 | try FileUtils.writeFile(to: readMeURL, fileText.data(using: .utf8))
32 | }
33 | }
34 |
35 | ApiParser.main()
36 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:6.0
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "EverscaleClientSwift",
8 | platforms: [
9 | .macOS(SupportedPlatform.MacOSVersion.v12),
10 | .iOS(SupportedPlatform.IOSVersion.v13)
11 | ],
12 | products: [
13 | .library(name: "EverscaleClientSwift", targets: ["EverscaleClientSwift"]),
14 | ],
15 | dependencies: [
16 | .package(url: "https://github.com/nerzh/swift-regular-expression.git", .upToNextMajor(from: "0.2.4")),
17 | .package(url: "https://github.com/nerzh/SwiftFileUtils", .upToNextMajor(from: "1.3.0")),
18 | .package(url: "https://github.com/bytehubio/BigInt", exact: "5.3.0"),
19 | .package(url: "https://github.com/nerzh/swift-extensions-pack", .upToNextMajor(from: "2.0.0")),
20 | ],
21 | targets: [
22 | .systemLibrary(name: "CTonSDK", pkgConfig: "libton_client"),
23 | .target(
24 | name: "EverscaleClientSwift",
25 | dependencies: [
26 | .byName(name: "CTonSDK"),
27 | .product(name: "SwiftRegularExpression", package: "swift-regular-expression"),
28 | .product(name: "BigInt", package: "BigInt"),
29 | .product(name: "SwiftExtensionsPack", package: "swift-extensions-pack"),
30 | ]),
31 | .testTarget(
32 | name: "EverscaleClientSwiftTests",
33 | dependencies: [
34 | .product(name: "SwiftRegularExpression", package: "swift-regular-expression"),
35 | .byName(name: "EverscaleClientSwift"),
36 | .product(name: "FileUtils", package: "SwiftFileUtils"),
37 | .product(name: "BigInt", package: "BigInt"),
38 | .product(name: "SwiftExtensionsPack", package: "swift-extensions-pack"),
39 | ]),
40 | ]
41 | )
42 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Swift Client for TVM SDK (everscale, venom, gosh)
2 |
3 |
10 |
11 | [](https://swift.org/package-manager/)
12 | [](https://github.com/tonlabs/ever-sdk)
13 |
14 | 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.
15 |
16 | | OS | Result |
17 | | ----------- | ----------- |
18 | | MacOS | ✅ |
19 | | Linux | ✅ |
20 | | iOS | ✅ |
21 | | Windows | Soon |
22 |
23 | ## Get api keys and TVM endpoints:
24 |
25 | You need to get an API-KEY here [https://dashboard.evercloud.dev](https://dashboard.evercloud.dev)
26 |
27 |
28 | ## Usage
29 |
30 | All requests are async
31 |
32 | ```swift
33 | import EverscaleClientSwift
34 |
35 | var config: TSDKClientConfig = .init()
36 | config.network = TSDKNetworkConfig(endpoints: ["https://net.ton.dev"])
37 | let client: TSDKClientModule = .init(config: config)
38 |
39 | // Crypto
40 | client.crypto.factorize(TSDKParamsOfFactorize(composite: "17ED48941A08F981")) { (response) in
41 | print(response.result?.factors)
42 | }
43 |
44 | // Boc
45 | let payload: TSDKParamsOfParse = .init(boc: "te6ccgEBAQEAWAAAq2n+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE/zMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzSsG8DgAAAAAjuOu9NAL7BxYpA")
46 | client.boc.parse_message(payload) { (response) in
47 | if let result = response.result, let parsed: [String: Any] = result.parsed.toDictionary() {
48 | print(parsed["id"])
49 | print(parsed["src"])
50 | print(parsed["dst"])
51 | }
52 | }
53 | ```
54 |
55 | ## Errors
56 |
57 | ```swift
58 | client.crypto.factorize(TSDKParamsOfFactorize(composite: "17ED48941A08F981")) { (response) in
59 | if let error = response.error {
60 | print(error.data.toJSON())
61 | print(error.code)
62 | }
63 | }
64 | ```
65 |
66 | ## Setup TONSDK For Linux and MacOS
67 |
68 | ### Install sdk with bash script
69 |
70 | 0. This download SDK to current dirrectory, compile it and add library symlinks to your system
71 | ```sh
72 | cd everscale-client-swift
73 | ```
74 |
75 | 1. For install or update the SDK version simply by running these command
76 | ```sh
77 | bash scripts/install_tonsdk.sh
78 | ```
79 |
80 | ### Manual install sdk ( if you have any problem with script install_tonsdk.sh )
81 |
82 |
83 | SPOILER: Manual installation
84 |
85 | 0. Install Rust to your OS
86 | 1. git clone https://github.com/tonlabs/ever-sdk
87 | 2. cd ./SDK
88 | 3. cargo update
89 | 4. cargo build --release
90 | 5. copy or create symlink of dynamic library
91 | __macOS :__
92 | **./SDK/target/release/libton_client.dylib**
93 | to
94 | **/usr/local/lib/libton_client.dylib**
95 |
96 | __Linux :__
97 | **./SDK/target/release/libton_client.so**
98 | to
99 | **/usr/lib/libton_client.so**
100 | 6. Create pkgConfig file :
101 |
102 | __macOS :__
103 | **/usr/local/lib/pkgconfig/libton_client.pc**
104 |
105 | ```bash
106 |
107 | prefix=/usr/local
108 | exec_prefix=${prefix}
109 | includedir=${prefix}/include
110 | libdir=${exec_prefix}/lib
111 |
112 | Name: ton_client
113 | Description: ton_client
114 | Version: 1.0.0
115 | Cflags: -I${includedir}
116 | Libs: -L${libdir} -lton_client
117 |
118 | ```
119 | __Linux:__
120 | **/usr/lib/pkgconfig/libton_client.pc**
121 |
122 | ```bash
123 | prefix=/usr
124 | exec_prefix=${prefix}
125 | includedir=${prefix}/include
126 | libdir=${exec_prefix}/lib
127 |
128 | Name: ton_client
129 | Description: ton_client
130 | Version: 1.0.0
131 | Cflags: -I${includedir}
132 | Libs: -L${libdir} -lton_client
133 | ```
134 | 7. Copy or create symlink of file
135 | **/SDK/ton_client/client/tonclient.h**
136 | to
137 | __MacOS:__
138 | **/usr/local/include/tonclient.h**
139 | __Linux:__
140 | **/usr/include/tonclient.h**
141 |
142 |
143 |
144 | ## Setup TONSDK For iOS
145 |
146 | 0. Install Rust
147 |
148 | ```bash
149 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh || true && \
150 | source ~/.profile
151 | ```
152 |
153 | 1. Install "cargo lipo"
154 |
155 | ```bash
156 | rustup target add aarch64-apple-ios x86_64-apple-ios || true && \
157 | cargo install cargo-lipo
158 | ```
159 |
160 | 2. Build SDK for iOS
161 |
162 | **Go to your project folder and:**
163 |
164 | ```bash
165 | git clone https://github.com/tonlabs/SDK.git || true && \
166 | cd ./SDK
167 | ```
168 |
169 | ```bash
170 | git pull --ff-only || true && \
171 | cargo update || true && \
172 | cargo lipo --release
173 | ```
174 | ⚠️ Wait installation
175 |
176 | 3. In xcode __File > Add files to "Name Your Project"__ navigate to ./SDK/ton_client/tonclient.h
177 |
178 | 4. Create bridge. In xcode __File > New > File__, select Header File, set name for example **Tonclient-Bridging-Header.h**
179 |
180 | and add
181 |
182 | __#include __
183 |
184 | __#import "tonclient.h"__
185 |
186 | like this:
187 |
188 | ```C
189 | #ifndef Tonclient_Bridging_Header_h
190 | #define Tonclient_Bridging_Header_h
191 |
192 | #include
193 | #import "tonclient.h"
194 |
195 | #endif
196 | ```
197 | 5. Add path to Tonclient-Bridging-Header.h **$(PROJECT_DIR)/Tonclient-Bridging-Header.h**
198 |
199 |
200 | 
201 |
202 | 6. Add path to search for libraries ( path to directory withlibton_client.a ) **$(PROJECT_DIR)/SDK/target/universal/release**
203 |
204 |
205 | 
206 |
207 | 7. __File > Swift Packages > Add Package Dependency__ **https://github.com/nerzh/ton-client-swift**
208 |
209 |
210 | 
211 |
212 | 8. Build project ...
213 |
214 | ## Tests
215 | ### If you use Xcode for Test
216 |
217 | Please, set custom working directory to project folder for your xcode scheme. This is necessary for the relative path "./" to this library folders.
218 | You may change it with the xcode edit scheme menu __Product > Scheme > Edit Scheme__ menu __Run__ submenu __Options__ enable checkbox "Use custom directory" and add custom working directory.
219 |
220 | Or if above variant not available, then inside file path_to_this_library/.swiftpm/xcode/xcshareddata/xcschemes/TonClientSwift.xcscheme
221 | set to tag __"LaunchAction"__ absolute path to this library with options:
222 | **useCustomWorkingDirectory = "YES"**
223 | **customWorkingDirectory = "/path_to_this_library"**
224 |
225 |
226 | ### Tests
227 |
228 | 1. inside root directory of everscale-client-swift create **.env.debug** file with
229 | NET TON DEV
230 | ```
231 | server_address=https://net.ton.dev
232 | giver_address=0:653b9a6452c7a982c6dc92b2da9eba832ade1c467699ebb3b43dca6d77b780dd
233 | giver_abi_name=Giver
234 | giver_function=grant
235 | ```
236 | **Optional:** Install locale NodeSE for tests if you needed:
237 | - launch docker
238 | - docker run -d --name local-node -p 80:80 tonlabs/local-node
239 | nodeSE will start on localhost:80
240 | ```
241 | server_address=http://localhost:80
242 | giver_abi_name=GiverNodeSE_v2
243 | giver_amount=10000000000
244 | ```
245 |
246 | 2. Run Tests
247 | __MacOS:__
248 | Run Tests inside Xcode
249 | __Linux:__
250 | swift test --generate-linuxmain
251 | swift test --enable-test-discovery
252 |
253 | ### Update SDK
254 |
255 | ```bash
256 | cd everscale-client-swift
257 | ```
258 | ```bash
259 | bash api_generate.sh
260 | ```
261 |
--------------------------------------------------------------------------------
/Sources/CTonSDK/module.modulemap:
--------------------------------------------------------------------------------
1 | module CTonSDK {
2 | header "shim.h"
3 | export *
4 | }
5 |
--------------------------------------------------------------------------------
/Sources/CTonSDK/shim.h:
--------------------------------------------------------------------------------
1 | #ifndef shim_h
2 | #define shim_h
3 | #include "stdbool.h"
4 | #include "tonclient.h"
5 | #endif
6 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Binding/Binding.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleh Hudeichuk on 18.10.2020.
3 | //
4 |
5 | import Foundation
6 | import CTonSDK
7 | import SwiftExtensionsPack
8 |
9 | public protocol TSDKBindingPrtcl {
10 |
11 | var context: UInt32 { get }
12 | static func convertToTSDKString(_ string: String, _ handler: (_ tsdkString: tc_string_data_t) throws -> Void) throws
13 | static func convertFromTSDKString(_ tsdkString: tc_string_data_t) throws -> String
14 | static func convertTSDKStringPointerToString(_ tsdkStringPointer: OpaquePointer) throws -> String
15 | static func convertTSDKStringToDictionary(_ tsdkString: tc_string_data_t) throws -> [String: Any]?
16 | static func convertTSDKStringPointerToDictionary(_ tsdkStringPointer: OpaquePointer) throws -> [String: Any]?
17 | }
18 |
19 |
20 | // MARK: Binding Helpers
21 |
22 | public final class TSDKBindingModule: TSDKBindingPrtcl {
23 |
24 | public var context: UInt32 = .init()
25 |
26 | public init(config: TSDKClientConfig = TSDKClientConfig()) throws {
27 | self.context = try createContext(config: config)
28 | }
29 |
30 | public static func convertToTSDKString(_ string: String, _ handler: (_ tsdkString: tc_string_data_t) throws -> Void) throws {
31 | try string.getPointer { (ptr: UnsafePointer, len: Int) in
32 | try handler(tc_string_data_t.init(content: ptr, len: UInt32(len)))
33 | }
34 | }
35 |
36 | public static func convertFromTSDKString(_ tsdkString: tc_string_data_t) throws -> String {
37 | let data = Data(bytes: tsdkString.content, count: Int(tsdkString.len))
38 | guard let s = String(data: data, encoding: .utf8) else {
39 | throw TSDKClientError.init(code: 0, message: "convertFromTSDKString NOT VALID")
40 | }
41 | return s
42 | }
43 |
44 | public static func convertTSDKStringPointerToString(_ tsdkStringPointer: OpaquePointer) -> String {
45 | let tsdkString: tc_string_data_t = tc_read_string(tsdkStringPointer)
46 | defer { tc_destroy_string(tsdkStringPointer) }
47 | return String(cString: UnsafeRawPointer(tsdkString.content).bindMemory(to: CChar.self, capacity: Int(tsdkString.len)))
48 | }
49 |
50 | public static func convertTSDKStringPointerToDictionary(_ tsdkStringPointer: OpaquePointer) -> [String: Any]? {
51 | let string: String = convertTSDKStringPointerToString(tsdkStringPointer)
52 | return string.toDictionary()
53 | }
54 |
55 | public static func convertTSDKStringToDictionary(_ tsdkString: tc_string_data_t) throws -> [String: Any]? {
56 | let string: String = try convertFromTSDKString(tsdkString)
57 | return string.toDictionary()
58 | }
59 |
60 | private func createContext(config: TSDKClientConfig) throws -> UInt32 {
61 | var contextId: UInt32 = .init()
62 | let json: String = config.toJson ?? "{}"
63 | try Self.convertToTSDKString(json) { config in
64 | let ctx: OpaquePointer = tc_create_context(config)
65 | let contextResponse: TSDKContextResponse = try Self.convertFromTSDKString(tc_read_string(ctx)).toModel(TSDKContextResponse.self)
66 | defer { tc_destroy_string(ctx) }
67 | if let context = contextResponse.result {
68 | contextId = context
69 | } else {
70 | fatalError(contextResponse.error.debugDescription)
71 | }
72 | }
73 | return contextId
74 | }
75 |
76 | public func destroyContext() {
77 | tc_destroy_context(context)
78 | }
79 |
80 | public func requestLibraryAsync(_ methodName: String,
81 | _ payload: Encodable = "",
82 | _ requestHandler: @escaping @Sendable (_ requestId: UInt32,
83 | _ stringResponse: String,
84 | _ responseType: TSDKBindingResponseType,
85 | _ finished: Bool) throws -> Void
86 | ) throws {
87 | try Self.convertToTSDKString(methodName) { [weak self] tsdkMethodName in
88 | guard let self = self else { return }
89 | let payload = payload.toJson ?? ""
90 | try Self.convertToTSDKString(payload) { tsdkPayload in
91 | let requestId: UInt32 = BindingStore.generate_request_id()
92 | BindingStore.addResponseHandler(requestId, requestHandler)
93 | tc_request(self.context,
94 | tsdkMethodName,
95 | tsdkPayload,
96 | requestId
97 | ) { (requestId: UInt32, params: tc_string_data_t, responseType: UInt32, finished: Bool) in
98 | let responseHandler = BindingStore.getResponseHandler(requestId)
99 | do {
100 | let swiftString: String = try TSDKBindingModule.convertFromTSDKString(params)
101 | let responseType: TSDKBindingResponseType = (TSDKBindingResponseType.init(rawValue: responseType) ?? .unknown)!
102 |
103 | try responseHandler?(requestId, swiftString, responseType, finished)
104 | if finished || responseType == .responseError {
105 | BindingStore.deleteResponseHandler(requestId)
106 | }
107 | } catch {
108 | BindingStore.deleteResponseHandler(requestId)
109 | try? responseHandler?(
110 | requestId,
111 | [
112 | "code": 0,
113 | "message": String(describing: error),
114 | "data": ([:] as [String: Any]).toAnyValue()
115 | ].toAnyValue().toJSON(),
116 | .responseError,
117 | true)
118 | }
119 | }
120 | }
121 | }
122 | }
123 |
124 | public func requestLibraryAsyncAwait(_ methodName: String,
125 | _ payload: Encodable = "",
126 | _ requestHandler: @escaping @Sendable (_ requestId: UInt32,
127 | _ stringResponse: String,
128 | _ responseType: TSDKBindingResponseType,
129 | _ finished: Bool) throws -> Void
130 | ) throws {
131 | try Self.convertToTSDKString(methodName) { [weak self] tsdkMethodName in
132 | guard let self = self else { return }
133 | let payload = payload.toJson ?? ""
134 | try Self.convertToTSDKString(payload) { tsdkPayload in
135 | let requestId: UInt32 = BindingStore.generate_request_id()
136 | BindingStore.addResponseHandler(requestId, requestHandler)
137 | tc_request(self.context,
138 | tsdkMethodName,
139 | tsdkPayload,
140 | requestId
141 | ) { (requestId: UInt32, params: tc_string_data_t, responseType: UInt32, finished: Bool) in
142 | let responseHandler = BindingStore.getResponseHandler(requestId)
143 | do {
144 | let swiftString: String = try TSDKBindingModule.convertFromTSDKString(params)
145 | let responseType: TSDKBindingResponseType = (TSDKBindingResponseType.init(rawValue: responseType) ?? .unknown)!
146 |
147 | if !swiftString.isEmpty {
148 | BindingStore.setCompleteResponse(requestId,
149 | (requestId: requestId,
150 | stringResponse: swiftString,
151 | responseType: responseType,
152 | finished: true))
153 | }
154 |
155 | if finished || responseType == .responseError {
156 | BindingStore.deleteResponseHandler(requestId)
157 | let response: BindingStore.RawResponse = try BindingStore.getCompleteResponse(requestId)
158 | try responseHandler?(response.requestId, response.stringResponse, response.responseType, response.finished)
159 | BindingStore.deleteCompleteResponse(requestId)
160 | }
161 | } catch {
162 | BindingStore.deleteResponseHandler(requestId)
163 | BindingStore.deleteCompleteResponse(requestId)
164 | try? responseHandler?(
165 | requestId,
166 | [
167 | "code": 0,
168 | "message": String(describing: error),
169 | "data": ([:] as [String: Any]).toAnyValue()
170 | ].toAnyValue().toJSON(),
171 | .responseError,
172 | true)
173 | }
174 | }
175 | }
176 | }
177 | }
178 |
179 | deinit {
180 | #if DEBUG
181 | print("destroyContext()")
182 | #endif
183 | destroyContext()
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Binding/BindingStore.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 19.10.2020.
6 | //
7 |
8 | import Foundation
9 |
10 | public final class BindingStore: @unchecked Sendable {
11 |
12 | nonisolated(unsafe) private static var requsetId: UInt32 = .init()
13 | private static let requestLock: NSLock = .init()
14 | private static let asyncResponseLock: NSLock = .init()
15 | nonisolated(unsafe) public static var responses: [UInt32: (_ requestId: UInt32,
16 | _ stringResponse: String,
17 | _ responseType: TSDKBindingResponseType,
18 | _ finished: Bool) throws -> Void] = .init()
19 |
20 | /// BECAUSE SDK METHODS LIKE PROCESS MESSAGE RETURNED TWO RESPONSE
21 | /// FIRST REAL RESPONSE AND LAST EMPTY STRING WITH STATUS FINISHED
22 | public typealias RawResponse = (requestId: UInt32,
23 | stringResponse: String,
24 | responseType: TSDKBindingResponseType,
25 | finished: Bool)
26 | nonisolated(unsafe) public static var completeResponses: [UInt32: RawResponse] = [:]
27 | nonisolated(unsafe) public static var completeResponsesLock: NSLock = .init()
28 |
29 | public class func setCompleteResponse(_ id: UInt32, _ response: RawResponse) {
30 | completeResponsesLock.lock()
31 | defer { completeResponsesLock.unlock() }
32 | completeResponses[id] = response
33 | }
34 |
35 | public class func getCompleteResponse(_ id: UInt32) throws -> RawResponse {
36 | completeResponsesLock.lock()
37 | defer { completeResponsesLock.unlock() }
38 | guard let result = completeResponses[id] else { throw TSDKClientError("\(id) not found") }
39 | return result
40 | }
41 |
42 | public class func deleteCompleteResponse(_ id: UInt32) {
43 | completeResponsesLock.lock()
44 | defer { completeResponsesLock.unlock() }
45 | completeResponses[id] = nil
46 | }
47 |
48 | public class func addResponseHandler(_ requestId: UInt32,
49 | _ response: @escaping @Sendable (_ requestId: UInt32,
50 | _ stringResponse: String,
51 | _ responseType: TSDKBindingResponseType,
52 | _ finished: Bool) throws -> Void
53 | ) {
54 | asyncResponseLock.lock()
55 | responses[requestId] = response
56 | asyncResponseLock.unlock()
57 | }
58 |
59 | public class func getResponseHandler(_ requestId: UInt32) -> ((_ requestId: UInt32,
60 | _ stringResponse: String,
61 | _ responseType: TSDKBindingResponseType,
62 | _ finished: Bool) throws -> Void)? {
63 | asyncResponseLock.lock()
64 | defer { asyncResponseLock.unlock() }
65 | return responses[requestId]
66 | }
67 |
68 | public class func deleteResponseHandler(_ requestId: UInt32) {
69 | asyncResponseLock.lock()
70 | defer { asyncResponseLock.unlock() }
71 | responses[requestId] = nil
72 | }
73 |
74 | public class func generate_request_id() -> UInt32 {
75 | requestLock.lock()
76 | defer { requestLock.unlock() }
77 | if requsetId == UInt32.max {
78 | requsetId = 0
79 | }
80 | requsetId += 1
81 | return requsetId
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Binding/BindingTypes.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleh Hudeichuk on 18.10.2020.
3 | //
4 |
5 | import Foundation
6 | import SwiftExtensionsPack
7 |
8 | public struct TSDKContextResponse: Codable {
9 | public var result: UInt32?
10 | public var error: AnyValue?
11 | }
12 |
13 | public struct TSDKBindingRequest {
14 | public var result: (_ result: TSDKResult?) -> Void
15 | public var error: (_ error: TSDKError?) -> Void
16 | public var customHandler: (_ params: TSDKCustom?) -> Void
17 | }
18 |
19 | public enum TSDKBindingResponseType: UInt32 {
20 | case responseSuccess = 0
21 | case responseError = 1
22 | case responseNop = 2
23 | case responseCustom = 100
24 | case unknown
25 | }
26 |
27 | public struct TSDKNoneResult: Codable, Sendable {}
28 |
29 | public struct TSDKDefault: Codable {
30 | public var result: AnyValue?
31 | public var error: AnyValue?
32 | public var data: AnyValue?
33 | public var message: AnyValue?
34 | public var code: AnyValue?
35 |
36 | public init(result: AnyValue? = nil, error: AnyValue? = nil, data: AnyValue? = nil, message: AnyValue? = nil, code: AnyValue? = nil) {
37 | self.result = result
38 | self.error = error
39 | self.data = data
40 | self.message = message
41 | self.code = code
42 | }
43 | }
44 |
45 | public struct TSDKBindingResponse {
46 | public var result: TSDKResult?
47 | public var error: TSDKError?
48 | public var dappError: TSDKError?
49 | public var finished: Bool = false
50 | public var requestId: UInt32 = 0
51 | public var rawResponse: String = .init()
52 |
53 | public init(result: TSDKResult? = nil,
54 | error: TSDKError? = nil,
55 | dappError: TSDKError? = nil,
56 | finished: Bool = false,
57 | requestId: UInt32 = 0,
58 | rawResponse: String = .init()
59 | ) {
60 | self.result = result
61 | self.error = error
62 | self.dappError = dappError
63 | self.finished = finished
64 | self.requestId = requestId
65 | self.rawResponse = rawResponse
66 | }
67 |
68 | public mutating func update(_ requestId: UInt32,
69 | _ rawResponse: String,
70 | _ responseType: TSDKBindingResponseType,
71 | _ finished: Bool
72 | ) {
73 | self.finished = finished
74 | self.requestId = requestId
75 | self.rawResponse = rawResponse
76 |
77 | switch responseType {
78 | case .responseSuccess:
79 | result = rawResponse.toModel(TSDKResult.self)
80 | case .responseError:
81 | error = rawResponse.toModel(TSDKError.self)
82 | Log.warn(error ?? "RESPONSE TYPE ERROR, BUT ERROR IS NIL")
83 | case .responseCustom:
84 | result = rawResponse.toModel(TSDKResult.self)
85 | case .responseNop:
86 | result = rawResponse.toModel(TSDKResult.self)
87 | default:
88 | dappError = rawResponse.toModel(TSDKError.self)
89 | Log.warn(error ?? "responseType NOT FOUND and dappError not parsed. Raw Response\n\(rawResponse)")
90 | }
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Client/Client.swift:
--------------------------------------------------------------------------------
1 | public final class TSDKClientModule {
2 |
3 | private var binding: TSDKBindingModule
4 | public let module: String = "client"
5 | public let config: TSDKClientConfig
6 | public var crypto: TSDKCryptoModule
7 | public var abi: TSDKAbiModule
8 | public var boc: TSDKBocModule
9 | public var processing: TSDKProcessingModule
10 | public var utils: TSDKUtilsModule
11 | public var tvm: TSDKTvmModule
12 | public var net: TSDKNetModule
13 | public var debot: TSDKDebotModule
14 | public var proofs: TSDKProofsModule
15 |
16 | public init(config: TSDKClientConfig) throws {
17 | self.config = config
18 | self.binding = try TSDKBindingModule(config: config)
19 | self.crypto = TSDKCryptoModule(binding: binding)
20 | self.abi = TSDKAbiModule(binding: binding)
21 | self.boc = TSDKBocModule(binding: binding)
22 | self.processing = TSDKProcessingModule(binding: binding)
23 | self.utils = TSDKUtilsModule(binding: binding)
24 | self.tvm = TSDKTvmModule(binding: binding)
25 | self.net = TSDKNetModule(binding: binding)
26 | self.debot = TSDKDebotModule(binding: binding)
27 | self.proofs = TSDKProofsModule(binding: binding)
28 | }
29 |
30 | /// Returns Core Library API reference
31 | public func get_api_reference(_ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
32 | ) throws {
33 | let method: String = "get_api_reference"
34 | try binding.requestLibraryAsync(methodName(module, method), "") { (requestId, params, responseType, finished) in
35 | var response: TSDKBindingResponse = .init()
36 | response.update(requestId, params, responseType, finished)
37 | try handler(response)
38 | }
39 | }
40 |
41 | /// Returns Core Library API reference
42 | @available(iOS 13, *)
43 | @available(macOS 12, *)
44 | public func get_api_reference() async throws -> TSDKResultOfGetApiReference {
45 | try await withCheckedThrowingContinuation { continuation in
46 | do {
47 | let method: String = "get_api_reference"
48 | try binding.requestLibraryAsyncAwait(methodName(module, method), "") { (requestId, params, responseType, finished) in
49 | var response: TSDKBindingResponse = .init()
50 | response.update(requestId, params, responseType, finished)
51 | if let error = response.error {
52 | continuation.resume(throwing: error)
53 | } else if let result = response.result {
54 | continuation.resume(returning: result)
55 | } else {
56 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
57 | }
58 | }
59 | } catch {
60 | continuation.resume(throwing: error)
61 | }
62 | }
63 | }
64 |
65 | /// Returns Core Library version
66 | public func version(_ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
67 | ) throws {
68 | let method: String = "version"
69 | try binding.requestLibraryAsync(methodName(module, method), "") { (requestId, params, responseType, finished) in
70 | var response: TSDKBindingResponse = .init()
71 | response.update(requestId, params, responseType, finished)
72 | try handler(response)
73 | }
74 | }
75 |
76 | /// Returns Core Library version
77 | @available(iOS 13, *)
78 | @available(macOS 12, *)
79 | public func version() async throws -> TSDKResultOfVersion {
80 | try await withCheckedThrowingContinuation { continuation in
81 | do {
82 | let method: String = "version"
83 | try binding.requestLibraryAsyncAwait(methodName(module, method), "") { (requestId, params, responseType, finished) in
84 | var response: TSDKBindingResponse = .init()
85 | response.update(requestId, params, responseType, finished)
86 | if let error = response.error {
87 | continuation.resume(throwing: error)
88 | } else if let result = response.result {
89 | continuation.resume(returning: result)
90 | } else {
91 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
92 | }
93 | }
94 | } catch {
95 | continuation.resume(throwing: error)
96 | }
97 | }
98 | }
99 |
100 | /// Returns Core Library API reference
101 | public func config(_ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
102 | ) throws {
103 | let method: String = "config"
104 | try binding.requestLibraryAsync(methodName(module, method), "") { (requestId, params, responseType, finished) in
105 | var response: TSDKBindingResponse = .init()
106 | response.update(requestId, params, responseType, finished)
107 | try handler(response)
108 | }
109 | }
110 |
111 | /// Returns Core Library API reference
112 | @available(iOS 13, *)
113 | @available(macOS 12, *)
114 | public func config() async throws -> TSDKClientConfig {
115 | try await withCheckedThrowingContinuation { continuation in
116 | do {
117 | let method: String = "config"
118 | try binding.requestLibraryAsyncAwait(methodName(module, method), "") { (requestId, params, responseType, finished) in
119 | var response: TSDKBindingResponse = .init()
120 | response.update(requestId, params, responseType, finished)
121 | if let error = response.error {
122 | continuation.resume(throwing: error)
123 | } else if let result = response.result {
124 | continuation.resume(returning: result)
125 | } else {
126 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
127 | }
128 | }
129 | } catch {
130 | continuation.resume(throwing: error)
131 | }
132 | }
133 | }
134 |
135 | /// Returns detailed information about this build.
136 | public func build_info(_ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
137 | ) throws {
138 | let method: String = "build_info"
139 | try binding.requestLibraryAsync(methodName(module, method), "") { (requestId, params, responseType, finished) in
140 | var response: TSDKBindingResponse = .init()
141 | response.update(requestId, params, responseType, finished)
142 | try handler(response)
143 | }
144 | }
145 |
146 | /// Returns detailed information about this build.
147 | @available(iOS 13, *)
148 | @available(macOS 12, *)
149 | public func build_info() async throws -> TSDKResultOfBuildInfo {
150 | try await withCheckedThrowingContinuation { continuation in
151 | do {
152 | let method: String = "build_info"
153 | try binding.requestLibraryAsyncAwait(methodName(module, method), "") { (requestId, params, responseType, finished) in
154 | var response: TSDKBindingResponse = .init()
155 | response.update(requestId, params, responseType, finished)
156 | if let error = response.error {
157 | continuation.resume(throwing: error)
158 | } else if let result = response.result {
159 | continuation.resume(returning: result)
160 | } else {
161 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
162 | }
163 | }
164 | } catch {
165 | continuation.resume(throwing: error)
166 | }
167 | }
168 | }
169 |
170 | /// Resolves application request processing result
171 | public func resolve_app_request(_ payload: TSDKParamsOfResolveAppRequest, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
172 | ) throws {
173 | let method: String = "resolve_app_request"
174 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
175 | var response: TSDKBindingResponse = .init()
176 | response.update(requestId, params, responseType, finished)
177 | try handler(response)
178 | }
179 | }
180 |
181 | /// Resolves application request processing result
182 | @available(iOS 13, *)
183 | @available(macOS 12, *)
184 | public func resolve_app_request(_ payload: TSDKParamsOfResolveAppRequest) async throws -> TSDKNoneResult {
185 | try await withCheckedThrowingContinuation { continuation in
186 | do {
187 | let method: String = "resolve_app_request"
188 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
189 | var response: TSDKBindingResponse = .init()
190 | response.update(requestId, params, responseType, finished)
191 | if let error = response.error {
192 | continuation.resume(throwing: error)
193 | } else if let result = response.result {
194 | continuation.resume(returning: result)
195 | } else {
196 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
197 | }
198 | }
199 | } catch {
200 | continuation.resume(throwing: error)
201 | }
202 | }
203 | }
204 |
205 | deinit {
206 | print("Client DEINIT !")
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Debot/DebotTypes.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import SwiftExtensionsPack
3 |
4 |
5 | public typealias TSDKDebotHandle = UInt32
6 |
7 | public enum TSDKDebotErrorCode: Int, Codable {
8 | case DebotStartFailed = 801
9 | case DebotFetchFailed = 802
10 | case DebotExecutionFailed = 803
11 | case DebotInvalidHandle = 804
12 | case DebotInvalidJsonParams = 805
13 | case DebotInvalidFunctionId = 806
14 | case DebotInvalidAbi = 807
15 | case DebotGetMethodFailed = 808
16 | case DebotInvalidMsg = 809
17 | case DebotExternalCallFailed = 810
18 | case DebotBrowserCallbackFailed = 811
19 | case DebotOperationRejected = 812
20 | case DebotNoCode = 813
21 | }
22 |
23 | public enum TSDKDebotActivityEnumTypes: String, Codable {
24 | case Transaction = "Transaction"
25 | }
26 |
27 | public enum TSDKParamsOfAppDebotBrowserEnumTypes: String, Codable {
28 | case Log = "Log"
29 | case Switch = "Switch"
30 | case SwitchCompleted = "SwitchCompleted"
31 | case ShowAction = "ShowAction"
32 | case Input = "Input"
33 | case GetSigningBox = "GetSigningBox"
34 | case InvokeDebot = "InvokeDebot"
35 | case Send = "Send"
36 | case Approve = "Approve"
37 | }
38 |
39 | public enum TSDKResultOfAppDebotBrowserEnumTypes: String, Codable {
40 | case Input = "Input"
41 | case GetSigningBox = "GetSigningBox"
42 | case InvokeDebot = "InvokeDebot"
43 | case Approve = "Approve"
44 | }
45 |
46 | public struct TSDKDebotAction: Codable, @unchecked Sendable {
47 | /// A short action description.
48 | /// Should be used by Debot Browser as name of menu item.
49 | public var description: String
50 | /// Depends on action type.
51 | /// Can be a debot function name or a print string (for Print Action).
52 | public var name: String
53 | /// Action type.
54 | public var action_type: UInt8
55 | /// ID of debot context to switch after action execution.
56 | public var to: UInt8
57 | /// Action attributes.
58 | /// In the form of "param=value,flag". attribute example: instant, args, fargs, sign.
59 | public var attributes: String
60 | /// Some internal action data.
61 | /// Used by debot only.
62 | public var misc: String
63 |
64 | public init(description: String, name: String, action_type: UInt8, to: UInt8, attributes: String, misc: String) {
65 | self.description = description
66 | self.name = name
67 | self.action_type = action_type
68 | self.to = to
69 | self.attributes = attributes
70 | self.misc = misc
71 | }
72 | }
73 |
74 | public struct TSDKDebotInfo: Codable, @unchecked Sendable {
75 | /// DeBot short name.
76 | public var name: String?
77 | /// DeBot semantic version.
78 | public var version: String?
79 | /// The name of DeBot deployer.
80 | public var publisher: String?
81 | /// Short info about DeBot.
82 | public var caption: String?
83 | /// The name of DeBot developer.
84 | public var author: String?
85 | /// TON address of author for questions and donations.
86 | public var support: String?
87 | /// String with the first messsage from DeBot.
88 | public var hello: String?
89 | /// String with DeBot interface language (ISO-639).
90 | public var language: String?
91 | /// String with DeBot ABI.
92 | public var dabi: String?
93 | /// DeBot icon.
94 | public var icon: String?
95 | /// Vector with IDs of DInterfaces used by DeBot.
96 | public var interfaces: [String]
97 | /// ABI version ("x.y") supported by DeBot
98 | public var dabiVersion: String
99 |
100 | public init(name: String? = nil, version: String? = nil, publisher: String? = nil, caption: String? = nil, author: String? = nil, support: String? = nil, hello: String? = nil, language: String? = nil, dabi: String? = nil, icon: String? = nil, interfaces: [String], dabiVersion: String) {
101 | self.name = name
102 | self.version = version
103 | self.publisher = publisher
104 | self.caption = caption
105 | self.author = author
106 | self.support = support
107 | self.hello = hello
108 | self.language = language
109 | self.dabi = dabi
110 | self.icon = icon
111 | self.interfaces = interfaces
112 | self.dabiVersion = dabiVersion
113 | }
114 | }
115 |
116 | public struct TSDKDebotActivity: Codable, @unchecked Sendable {
117 | public var type: TSDKDebotActivityEnumTypes
118 | /// External inbound message BOC.
119 | public var msg: String?
120 | /// Target smart contract address.
121 | public var dst: String?
122 | /// List of spendings as a result of transaction.
123 | public var out: [TSDKSpending]?
124 | /// Transaction total fee.
125 | public var fee: Int?
126 | /// Indicates if target smart contract updates its code.
127 | public var setcode: Bool?
128 | /// Public key from keypair that was used to sign external message.
129 | public var signkey: String?
130 | /// Signing box handle used to sign external message.
131 | public var signing_box_handle: UInt32?
132 |
133 | public init(type: TSDKDebotActivityEnumTypes, msg: String? = nil, dst: String? = nil, out: [TSDKSpending]? = nil, fee: Int? = nil, setcode: Bool? = nil, signkey: String? = nil, signing_box_handle: UInt32? = nil) {
134 | self.type = type
135 | self.msg = msg
136 | self.dst = dst
137 | self.out = out
138 | self.fee = fee
139 | self.setcode = setcode
140 | self.signkey = signkey
141 | self.signing_box_handle = signing_box_handle
142 | }
143 | }
144 |
145 | /// [UNSTABLE](UNSTABLE.md) [DEPRECATED](DEPRECATED.md) Describes the operation that the DeBot wants to perform.
146 | public struct TSDKSpending: Codable, @unchecked Sendable {
147 | /// Amount of nanotokens that will be sent to `dst` address.
148 | public var amount: Int
149 | /// Destination address of recipient of funds.
150 | public var dst: String
151 |
152 | public init(amount: Int, dst: String) {
153 | self.amount = amount
154 | self.dst = dst
155 | }
156 | }
157 |
158 | public struct TSDKParamsOfInit: Codable, @unchecked Sendable {
159 | /// Debot smart contract address
160 | public var address: String
161 |
162 | public init(address: String) {
163 | self.address = address
164 | }
165 | }
166 |
167 | public struct TSDKRegisteredDebot: Codable, @unchecked Sendable {
168 | /// Debot handle which references an instance of debot engine.
169 | public var debot_handle: TSDKDebotHandle
170 | /// Debot abi as json string.
171 | public var debot_abi: String
172 | /// Debot metadata.
173 | public var info: TSDKDebotInfo
174 |
175 | public init(debot_handle: TSDKDebotHandle, debot_abi: String, info: TSDKDebotInfo) {
176 | self.debot_handle = debot_handle
177 | self.debot_abi = debot_abi
178 | self.info = info
179 | }
180 | }
181 |
182 | public struct TSDKParamsOfAppDebotBrowser: Codable, @unchecked Sendable {
183 | public var type: TSDKParamsOfAppDebotBrowserEnumTypes
184 | /// A string that must be printed to user.
185 | public var msg: String?
186 | /// Debot context ID to which debot is switched.
187 | public var context_id: UInt8?
188 | /// Debot action that must be shown to user as menu item. At least `description` property must be shown from [DebotAction] structure.
189 | public var action: TSDKDebotAction?
190 | /// A prompt string that must be printed to user before input request.
191 | public var prompt: String?
192 | /// Address of debot in blockchain.
193 | public var debot_addr: String?
194 | /// Internal message to DInterface address.
195 | /// Message body contains interface function and parameters.
196 | public var message: String?
197 | /// DeBot activity details.
198 | public var activity: TSDKDebotActivity?
199 |
200 | public init(type: TSDKParamsOfAppDebotBrowserEnumTypes, msg: String? = nil, context_id: UInt8? = nil, action: TSDKDebotAction? = nil, prompt: String? = nil, debot_addr: String? = nil, message: String? = nil, activity: TSDKDebotActivity? = nil) {
201 | self.type = type
202 | self.msg = msg
203 | self.context_id = context_id
204 | self.action = action
205 | self.prompt = prompt
206 | self.debot_addr = debot_addr
207 | self.message = message
208 | self.activity = activity
209 | }
210 | }
211 |
212 | /// [UNSTABLE](UNSTABLE.md) [DEPRECATED](DEPRECATED.md) Debot Browser callbacks
213 | /// Called by debot engine to communicate with debot browser.
214 | public struct TSDKResultOfAppDebotBrowser: Codable, @unchecked Sendable {
215 | public var type: TSDKResultOfAppDebotBrowserEnumTypes
216 | /// String entered by user.
217 | public var value: String?
218 | /// Signing box for signing data requested by debot engine.
219 | /// Signing box is owned and disposed by debot engine
220 | public var signing_box: TSDKSigningBoxHandle?
221 | /// Indicates whether the DeBot is allowed to perform the specified operation.
222 | public var approved: Bool?
223 |
224 | public init(type: TSDKResultOfAppDebotBrowserEnumTypes, value: String? = nil, signing_box: TSDKSigningBoxHandle? = nil, approved: Bool? = nil) {
225 | self.type = type
226 | self.value = value
227 | self.signing_box = signing_box
228 | self.approved = approved
229 | }
230 | }
231 |
232 | /// [UNSTABLE](UNSTABLE.md) [DEPRECATED](DEPRECATED.md) Returning values from Debot Browser callbacks.
233 | public struct TSDKParamsOfStart: Codable, @unchecked Sendable {
234 | /// Debot handle which references an instance of debot engine.
235 | public var debot_handle: TSDKDebotHandle
236 |
237 | public init(debot_handle: TSDKDebotHandle) {
238 | self.debot_handle = debot_handle
239 | }
240 | }
241 |
242 | public struct TSDKParamsOfFetch: Codable, @unchecked Sendable {
243 | /// Debot smart contract address.
244 | public var address: String
245 |
246 | public init(address: String) {
247 | self.address = address
248 | }
249 | }
250 |
251 | public struct TSDKResultOfFetch: Codable, @unchecked Sendable {
252 | /// Debot metadata.
253 | public var info: TSDKDebotInfo
254 |
255 | public init(info: TSDKDebotInfo) {
256 | self.info = info
257 | }
258 | }
259 |
260 | public struct TSDKParamsOfExecute: Codable, @unchecked Sendable {
261 | /// Debot handle which references an instance of debot engine.
262 | public var debot_handle: TSDKDebotHandle
263 | /// Debot Action that must be executed.
264 | public var action: TSDKDebotAction
265 |
266 | public init(debot_handle: TSDKDebotHandle, action: TSDKDebotAction) {
267 | self.debot_handle = debot_handle
268 | self.action = action
269 | }
270 | }
271 |
272 | public struct TSDKParamsOfSend: Codable, @unchecked Sendable {
273 | /// Debot handle which references an instance of debot engine.
274 | public var debot_handle: TSDKDebotHandle
275 | /// BOC of internal message to debot encoded in base64 format.
276 | public var message: String
277 |
278 | public init(debot_handle: TSDKDebotHandle, message: String) {
279 | self.debot_handle = debot_handle
280 | self.message = message
281 | }
282 | }
283 |
284 | public struct TSDKParamsOfRemove: Codable, @unchecked Sendable {
285 | /// Debot handle which references an instance of debot engine.
286 | public var debot_handle: TSDKDebotHandle
287 |
288 | public init(debot_handle: TSDKDebotHandle) {
289 | self.debot_handle = debot_handle
290 | }
291 | }
292 |
293 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Extensions/FileReader.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 22.10.2020.
6 | //
7 |
8 | import Foundation
9 |
10 | public final class DOFileReader {
11 |
12 | public let fileURL: URL
13 | private var file: UnsafeMutablePointer? = nil
14 |
15 | public init(fileURL: URL) {
16 | self.fileURL = fileURL
17 | }
18 |
19 | deinit {
20 | if self.file != nil { fatalError("Please, close file descriptor.") }
21 | }
22 |
23 | public func open(options: String = "r") throws {
24 | guard let descriptor = fopen(fileURL.path, options) else {
25 | throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)
26 | }
27 | self.file = descriptor
28 | }
29 |
30 | public func close() {
31 | if let descriptor = self.file {
32 | self.file = nil
33 | let success: Bool = fclose(descriptor) == 0
34 | assert(success)
35 | }
36 | }
37 |
38 | public func readLine(maxLength: Int = 4096) throws -> String? {
39 | guard let descriptor = self.file else {
40 | throw NSError(domain: NSPOSIXErrorDomain, code: Int(EBADF), userInfo: nil)
41 | }
42 | var buffer = [CChar](repeating: 0, count: maxLength)
43 | guard fgets(&buffer, Int32(maxLength), descriptor) != nil else {
44 | if feof(descriptor) != 0 {
45 | return nil
46 | } else {
47 | throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: nil)
48 | }
49 | }
50 |
51 | return String(cString: buffer)
52 | }
53 |
54 | public static func readFile(_ fileURL: URL, _ options: String = "r", _ handler: (_ line: String) -> Void) {
55 | let file: DOFileReader = .init(fileURL: fileURL)
56 | do {
57 | try file.open(options: options)
58 | defer { file.close() }
59 | while let line: String = try file.readLine() {
60 | handler(line)
61 | }
62 | } catch let error {
63 | let message: String = "Please, check working directory in schema for this project. Current workingDirectory is \(ProcessInfo.processInfo.environment["PWD"])"
64 | fatalError("\(String(describing: error)) \(message) ErrorFilePath: \(fileURL.path)")
65 | }
66 | }
67 |
68 | public static func readFile(_ filePath: String, _ options: String = "r", _ handler: (_ line: String) -> Void) {
69 | guard let fileURL: URL = URL(string: filePath) else { fatalError("Can not convert \(filePath) to URL") }
70 | readFile(fileURL, options, handler)
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Extensions/Helpers.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleh Hudeichuk on 18.10.2020.
3 | //
4 |
5 | import Foundation
6 |
7 | func methodName(_ module: String, _ method: String) -> String {
8 | "\(module).\(method)"
9 | }
10 |
11 | class Log {
12 |
13 | class func log(_ str: Any...) {
14 | print("❇️ logi:", str)
15 | }
16 |
17 | class func warn(_ str: Any...) {
18 | print("⚠️ logi:", str)
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Extensions/SimpleEnv.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleh Hudeichuk on 17.11.2020.
3 | //
4 |
5 | import Foundation
6 | import SwiftRegularExpression
7 |
8 |
9 | public final class SimpleEnv {
10 |
11 | nonisolated(unsafe) private static var env: [String: String] = .init()
12 | private static let debugEnvName: String = "debug"
13 | private static let adhocEnvName: String = "production"
14 | private static let productionEnvName: String = "production"
15 |
16 | nonisolated(unsafe) public static var path: String = "./"
17 |
18 | public class subscript(_ key: String) -> String? {
19 | if env.count == 0 {
20 | parseEnv()
21 | }
22 | return env[key]
23 | }
24 |
25 | private class func parseEnv() {
26 | #if DEBUG
27 | let environment: String = debugEnvName
28 | #elseif ADHOC
29 | let environment: String = adhocEnvName
30 | #else
31 | let environment: String = productionEnvName
32 | #endif
33 |
34 | let envFileName: String = ".env.\(environment)"
35 | let envFilePath: String = "\(path)/\(envFileName)"
36 | if !FileManager.default.fileExists(atPath: envFilePath) { return }
37 |
38 | DOFileReader.readFile("\(path)/\(envFileName)") { (line) in
39 | let line = line.trimmingCharacters(in: .whitespacesAndNewlines)
40 | let matchesWithQuotes: [Int: String] = line.regexp(#"\"([\s\S]+)\"\s*=\s*\"([\s\S]+)\""#)
41 | if line[#"^\/\/"#] { return }
42 | if let key: String = matchesWithQuotes[1], let value: String = matchesWithQuotes[2] {
43 | env[key] = value
44 | return
45 | }
46 | let matchesWithOutQuotes: [Int: String] = line.regexp(#"([\s\S]+)\s*=\s*([\s\S]+)"#)
47 | if let key: String = matchesWithOutQuotes[1], let value: String = matchesWithOutQuotes[2] {
48 | env[key] = value
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Proofs/ProofsTypes.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import SwiftExtensionsPack
3 |
4 |
5 | public enum TSDKProofsErrorCode: Int, Codable {
6 | case InvalidData = 901
7 | case ProofCheckFailed = 902
8 | case InternalError = 903
9 | case DataDiffersFromProven = 904
10 | }
11 |
12 | public struct TSDKParamsOfProofBlockData: Codable, @unchecked Sendable {
13 | /// Single block's data, retrieved from TONOS API, that needs proof. Required fields are `id` and/or top-level `boc` (for block identification), others are optional.
14 | public var block: AnyValue
15 |
16 | public init(block: AnyValue) {
17 | self.block = block
18 | }
19 | }
20 |
21 | public struct TSDKParamsOfProofTransactionData: Codable, @unchecked Sendable {
22 | /// Single transaction's data as queried from DApp server, without modifications. The required fields are `id` and/or top-level `boc`, others are optional. In order to reduce network requests count, it is recommended to provide `block_id` and `boc` of transaction.
23 | public var transaction: AnyValue
24 |
25 | public init(transaction: AnyValue) {
26 | self.transaction = transaction
27 | }
28 | }
29 |
30 | public struct TSDKParamsOfProofMessageData: Codable, @unchecked Sendable {
31 | /// Single message's data as queried from DApp server, without modifications. The required fields are `id` and/or top-level `boc`, others are optional. In order to reduce network requests count, it is recommended to provide at least `boc` of message and non-null `src_transaction.id` or `dst_transaction.id`.
32 | public var message: AnyValue
33 |
34 | public init(message: AnyValue) {
35 | self.message = message
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Tvm/Tvm.swift:
--------------------------------------------------------------------------------
1 | public final class TSDKTvmModule {
2 |
3 | private var binding: TSDKBindingModule
4 | public let module: String = "tvm"
5 |
6 | public init(binding: TSDKBindingModule) {
7 | self.binding = binding
8 | }
9 |
10 | /// Emulates all the phases of contract execution locally
11 | /// Performs all the phases of contract execution on Transaction Executor -the same component that is used on Validator Nodes.
12 | /// Can be used for contract debugging, to find out the reason why a message was not delivered successfully.
13 | /// Validators throw away the failed external inbound messages (if they failed before `ACCEPT`) in the real network.
14 | /// This is why these messages are impossible to debug in the real network.
15 | /// With the help of run_executor you can do that. In fact, `process_message` functionperforms local check with `run_executor` if there was no transaction as a result of processingand returns the error, if there is one.
16 | /// Another use case to use `run_executor` is to estimate fees for message execution.
17 | /// Set `AccountForExecutor::Account.unlimited_balance`to `true` so that emulation will not depend on the actual balance.
18 | /// This may be needed to calculate deploy fees for an account that does not exist yet.
19 | /// JSON with fees is in `fees` field of the result.
20 | /// One more use case - you can produce the sequence of operations,thus emulating the sequential contract calls locally.
21 | /// And so on.
22 | /// Transaction executor requires account BOC (bag of cells) as a parameter.
23 | /// To get the account BOC - use `net.query` method to download it from GraphQL API(field `boc` of `account`) or generate it with `abi.encode_account` method.
24 | /// Also it requires message BOC. To get the message BOC - use `abi.encode_message` or `abi.encode_internal_message`.
25 | /// If you need this emulation to be as precise as possible (for instance - emulate transactionwith particular lt in particular block or use particular blockchain config,downloaded from a particular key block - then specify `execution_options` parameter.
26 | /// If you need to see the aborted transaction as a result, not as an error, set `skip_transaction_check` to `true`.
27 | public func run_executor(_ payload: TSDKParamsOfRunExecutor, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
28 | ) throws {
29 | let method: String = "run_executor"
30 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
31 | var response: TSDKBindingResponse = .init()
32 | response.update(requestId, params, responseType, finished)
33 | try handler(response)
34 | }
35 | }
36 |
37 | /// Emulates all the phases of contract execution locally
38 | /// Performs all the phases of contract execution on Transaction Executor -the same component that is used on Validator Nodes.
39 | /// Can be used for contract debugging, to find out the reason why a message was not delivered successfully.
40 | /// Validators throw away the failed external inbound messages (if they failed before `ACCEPT`) in the real network.
41 | /// This is why these messages are impossible to debug in the real network.
42 | /// With the help of run_executor you can do that. In fact, `process_message` functionperforms local check with `run_executor` if there was no transaction as a result of processingand returns the error, if there is one.
43 | /// Another use case to use `run_executor` is to estimate fees for message execution.
44 | /// Set `AccountForExecutor::Account.unlimited_balance`to `true` so that emulation will not depend on the actual balance.
45 | /// This may be needed to calculate deploy fees for an account that does not exist yet.
46 | /// JSON with fees is in `fees` field of the result.
47 | /// One more use case - you can produce the sequence of operations,thus emulating the sequential contract calls locally.
48 | /// And so on.
49 | /// Transaction executor requires account BOC (bag of cells) as a parameter.
50 | /// To get the account BOC - use `net.query` method to download it from GraphQL API(field `boc` of `account`) or generate it with `abi.encode_account` method.
51 | /// Also it requires message BOC. To get the message BOC - use `abi.encode_message` or `abi.encode_internal_message`.
52 | /// If you need this emulation to be as precise as possible (for instance - emulate transactionwith particular lt in particular block or use particular blockchain config,downloaded from a particular key block - then specify `execution_options` parameter.
53 | /// If you need to see the aborted transaction as a result, not as an error, set `skip_transaction_check` to `true`.
54 | @available(iOS 13, *)
55 | @available(macOS 12, *)
56 | public func run_executor(_ payload: TSDKParamsOfRunExecutor) async throws -> TSDKResultOfRunExecutor {
57 | try await withCheckedThrowingContinuation { continuation in
58 | do {
59 | let method: String = "run_executor"
60 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
61 | var response: TSDKBindingResponse = .init()
62 | response.update(requestId, params, responseType, finished)
63 | if let error = response.error {
64 | continuation.resume(throwing: error)
65 | } else if let result = response.result {
66 | continuation.resume(returning: result)
67 | } else {
68 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
69 | }
70 | }
71 | } catch {
72 | continuation.resume(throwing: error)
73 | }
74 | }
75 | }
76 |
77 | /// Executes get-methods of ABI-compatible contracts
78 | /// Performs only a part of compute phase of transaction executionthat is used to run get-methods of ABI-compatible contracts.
79 | /// If you try to run get-methods with `run_executor` you will get an error, because it checks ACCEPT and exitsif there is none, which is actually true for get-methods.
80 | /// To get the account BOC (bag of cells) - use `net.query` method to download it from GraphQL API(field `boc` of `account`) or generate it with `abi.encode_account method`.
81 | /// To get the message BOC - use `abi.encode_message` or prepare it any other way, for instance, with FIFT script.
82 | /// Attention! Updated account state is produces as well, but only`account_state.storage.state.data` part of the BOC is updated.
83 | public func run_tvm(_ payload: TSDKParamsOfRunTvm, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
84 | ) throws {
85 | let method: String = "run_tvm"
86 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
87 | var response: TSDKBindingResponse = .init()
88 | response.update(requestId, params, responseType, finished)
89 | try handler(response)
90 | }
91 | }
92 |
93 | /// Executes get-methods of ABI-compatible contracts
94 | /// Performs only a part of compute phase of transaction executionthat is used to run get-methods of ABI-compatible contracts.
95 | /// If you try to run get-methods with `run_executor` you will get an error, because it checks ACCEPT and exitsif there is none, which is actually true for get-methods.
96 | /// To get the account BOC (bag of cells) - use `net.query` method to download it from GraphQL API(field `boc` of `account`) or generate it with `abi.encode_account method`.
97 | /// To get the message BOC - use `abi.encode_message` or prepare it any other way, for instance, with FIFT script.
98 | /// Attention! Updated account state is produces as well, but only`account_state.storage.state.data` part of the BOC is updated.
99 | @available(iOS 13, *)
100 | @available(macOS 12, *)
101 | public func run_tvm(_ payload: TSDKParamsOfRunTvm) async throws -> TSDKResultOfRunTvm {
102 | try await withCheckedThrowingContinuation { continuation in
103 | do {
104 | let method: String = "run_tvm"
105 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
106 | var response: TSDKBindingResponse = .init()
107 | response.update(requestId, params, responseType, finished)
108 | if let error = response.error {
109 | continuation.resume(throwing: error)
110 | } else if let result = response.result {
111 | continuation.resume(returning: result)
112 | } else {
113 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
114 | }
115 | }
116 | } catch {
117 | continuation.resume(throwing: error)
118 | }
119 | }
120 | }
121 |
122 | /// Executes a get-method of FIFT contract
123 | /// Executes a get-method of FIFT contract that fulfills the smc-guidelines https://test.ton.org/smc-guidelines.txtand returns the result data from TVM's stack
124 | public func run_get(_ payload: TSDKParamsOfRunGet, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
125 | ) throws {
126 | let method: String = "run_get"
127 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
128 | var response: TSDKBindingResponse = .init()
129 | response.update(requestId, params, responseType, finished)
130 | try handler(response)
131 | }
132 | }
133 |
134 | /// Executes a get-method of FIFT contract
135 | /// Executes a get-method of FIFT contract that fulfills the smc-guidelines https://test.ton.org/smc-guidelines.txtand returns the result data from TVM's stack
136 | @available(iOS 13, *)
137 | @available(macOS 12, *)
138 | public func run_get(_ payload: TSDKParamsOfRunGet) async throws -> TSDKResultOfRunGet {
139 | try await withCheckedThrowingContinuation { continuation in
140 | do {
141 | let method: String = "run_get"
142 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
143 | var response: TSDKBindingResponse = .init()
144 | response.update(requestId, params, responseType, finished)
145 | if let error = response.error {
146 | continuation.resume(throwing: error)
147 | } else if let result = response.result {
148 | continuation.resume(returning: result)
149 | } else {
150 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
151 | }
152 | }
153 | } catch {
154 | continuation.resume(throwing: error)
155 | }
156 | }
157 | }
158 |
159 | }
160 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Tvm/TvmTypes.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import SwiftExtensionsPack
3 |
4 |
5 | public enum TSDKTvmErrorCode: Int, Codable {
6 | case CanNotReadTransaction = 401
7 | case CanNotReadBlockchainConfig = 402
8 | case TransactionAborted = 403
9 | case InternalError = 404
10 | case ActionPhaseFailed = 405
11 | case AccountCodeMissing = 406
12 | case LowBalance = 407
13 | case AccountFrozenOrDeleted = 408
14 | case AccountMissing = 409
15 | case UnknownExecutionError = 410
16 | case InvalidInputStack = 411
17 | case InvalidAccountBoc = 412
18 | case InvalidMessageType = 413
19 | case ContractExecutionError = 414
20 | case AccountIsSuspended = 415
21 | }
22 |
23 | public enum TSDKAccountForExecutorEnumTypes: String, Codable {
24 | case None = "None"
25 | case Uninit = "Uninit"
26 | case Account = "Account"
27 | }
28 |
29 | public struct TSDKExecutionOptions: Codable, @unchecked Sendable {
30 | /// boc with config
31 | public var blockchain_config: String?
32 | /// time that is used as transaction time
33 | public var block_time: UInt32?
34 | /// block logical time
35 | public var block_lt: Int?
36 | /// transaction logical time
37 | public var transaction_lt: Int?
38 | /// Overrides standard TVM behaviour. If set to `true` then CHKSIG always will return `true`.
39 | public var chksig_always_succeed: Bool?
40 | /// Signature ID to be used in signature verifying instructions when CapSignatureWithId capability is enabled
41 | public var signature_id: Int32?
42 |
43 | public init(blockchain_config: String? = nil, block_time: UInt32? = nil, block_lt: Int? = nil, transaction_lt: Int? = nil, chksig_always_succeed: Bool? = nil, signature_id: Int32? = nil) {
44 | self.blockchain_config = blockchain_config
45 | self.block_time = block_time
46 | self.block_lt = block_lt
47 | self.transaction_lt = transaction_lt
48 | self.chksig_always_succeed = chksig_always_succeed
49 | self.signature_id = signature_id
50 | }
51 | }
52 |
53 | public struct TSDKAccountForExecutor: Codable, @unchecked Sendable {
54 | public var type: TSDKAccountForExecutorEnumTypes
55 | /// Account BOC.
56 | /// Encoded as base64.
57 | public var boc: String?
58 | /// Flag for running account with the unlimited balance.
59 | /// Can be used to calculate transaction fees without balance check
60 | public var unlimited_balance: Bool?
61 |
62 | public init(type: TSDKAccountForExecutorEnumTypes, boc: String? = nil, unlimited_balance: Bool? = nil) {
63 | self.type = type
64 | self.boc = boc
65 | self.unlimited_balance = unlimited_balance
66 | }
67 | }
68 |
69 | public struct TSDKTransactionFees: Codable, @unchecked Sendable {
70 | /// Deprecated.
71 | /// Contains the same data as ext_in_msg_fee field
72 | public var in_msg_fwd_fee: Int
73 | /// Fee for account storage
74 | public var storage_fee: Int
75 | /// Fee for processing
76 | public var gas_fee: Int
77 | /// Deprecated.
78 | /// Contains the same data as total_fwd_fees field. Deprecated because of its confusing name, that is not the same with GraphQL API Transaction type's field.
79 | public var out_msgs_fwd_fee: Int
80 | /// Deprecated.
81 | /// Contains the same data as account_fees field
82 | public var total_account_fees: Int
83 | /// Deprecated because it means total value sent in the transaction, which does not relate to any fees.
84 | public var total_output: Int
85 | /// Fee for inbound external message import.
86 | public var ext_in_msg_fee: Int
87 | /// Total fees the account pays for message forwarding
88 | public var total_fwd_fees: Int
89 | /// Total account fees for the transaction execution. Compounds of storage_fee + gas_fee + ext_in_msg_fee + total_fwd_fees
90 | public var account_fees: Int
91 |
92 | public init(in_msg_fwd_fee: Int, storage_fee: Int, gas_fee: Int, out_msgs_fwd_fee: Int, total_account_fees: Int, total_output: Int, ext_in_msg_fee: Int, total_fwd_fees: Int, account_fees: Int) {
93 | self.in_msg_fwd_fee = in_msg_fwd_fee
94 | self.storage_fee = storage_fee
95 | self.gas_fee = gas_fee
96 | self.out_msgs_fwd_fee = out_msgs_fwd_fee
97 | self.total_account_fees = total_account_fees
98 | self.total_output = total_output
99 | self.ext_in_msg_fee = ext_in_msg_fee
100 | self.total_fwd_fees = total_fwd_fees
101 | self.account_fees = account_fees
102 | }
103 | }
104 |
105 | public struct TSDKParamsOfRunExecutor: Codable, @unchecked Sendable {
106 | /// Input message BOC.
107 | /// Must be encoded as base64.
108 | public var message: String
109 | /// Account to run on executor
110 | public var account: TSDKAccountForExecutor
111 | /// Execution options.
112 | public var execution_options: TSDKExecutionOptions?
113 | /// Contract ABI for decoding output messages
114 | public var abi: TSDKAbi?
115 | /// Skip transaction check flag
116 | public var skip_transaction_check: Bool?
117 | /// Cache type to put the result.
118 | /// The BOC itself returned if no cache type provided
119 | public var boc_cache: TSDKBocCacheType?
120 | /// Return updated account flag.
121 | /// Empty string is returned if the flag is `false`
122 | public var return_updated_account: Bool?
123 |
124 | public init(message: String, account: TSDKAccountForExecutor, execution_options: TSDKExecutionOptions? = nil, abi: TSDKAbi? = nil, skip_transaction_check: Bool? = nil, boc_cache: TSDKBocCacheType? = nil, return_updated_account: Bool? = nil) {
125 | self.message = message
126 | self.account = account
127 | self.execution_options = execution_options
128 | self.abi = abi
129 | self.skip_transaction_check = skip_transaction_check
130 | self.boc_cache = boc_cache
131 | self.return_updated_account = return_updated_account
132 | }
133 | }
134 |
135 | public struct TSDKResultOfRunExecutor: Codable, @unchecked Sendable {
136 | /// Parsed transaction.
137 | /// In addition to the regular transaction fields there is a`boc` field encoded with `base64` which contains sourcetransaction BOC.
138 | public var transaction: AnyValue
139 | /// List of output messages' BOCs.
140 | /// Encoded as `base64`
141 | public var out_messages: [String]
142 | /// Optional decoded message bodies according to the optional `abi` parameter.
143 | public var decoded: TSDKDecodedOutput?
144 | /// Updated account state BOC.
145 | /// Encoded as `base64`
146 | public var account: String
147 | /// Transaction fees
148 | public var fees: TSDKTransactionFees
149 |
150 | public init(transaction: AnyValue, out_messages: [String], decoded: TSDKDecodedOutput? = nil, account: String, fees: TSDKTransactionFees) {
151 | self.transaction = transaction
152 | self.out_messages = out_messages
153 | self.decoded = decoded
154 | self.account = account
155 | self.fees = fees
156 | }
157 | }
158 |
159 | public struct TSDKParamsOfRunTvm: Codable, @unchecked Sendable {
160 | /// Input message BOC.
161 | /// Must be encoded as base64.
162 | public var message: String
163 | /// Account BOC.
164 | /// Must be encoded as base64.
165 | public var account: String
166 | /// Execution options.
167 | public var execution_options: TSDKExecutionOptions?
168 | /// Contract ABI for decoding output messages
169 | public var abi: TSDKAbi?
170 | /// Cache type to put the result.
171 | /// The BOC itself returned if no cache type provided
172 | public var boc_cache: TSDKBocCacheType?
173 | /// Return updated account flag.
174 | /// Empty string is returned if the flag is `false`
175 | public var return_updated_account: Bool?
176 |
177 | public init(message: String, account: String, execution_options: TSDKExecutionOptions? = nil, abi: TSDKAbi? = nil, boc_cache: TSDKBocCacheType? = nil, return_updated_account: Bool? = nil) {
178 | self.message = message
179 | self.account = account
180 | self.execution_options = execution_options
181 | self.abi = abi
182 | self.boc_cache = boc_cache
183 | self.return_updated_account = return_updated_account
184 | }
185 | }
186 |
187 | public struct TSDKResultOfRunTvm: Codable, @unchecked Sendable {
188 | /// List of output messages' BOCs.
189 | /// Encoded as `base64`
190 | public var out_messages: [String]
191 | /// Optional decoded message bodies according to the optional `abi` parameter.
192 | public var decoded: TSDKDecodedOutput?
193 | /// Updated account state BOC.
194 | /// Encoded as `base64`. Attention! Only `account_state.storage.state.data` part of the BOC is updated.
195 | public var account: String
196 |
197 | public init(out_messages: [String], decoded: TSDKDecodedOutput? = nil, account: String) {
198 | self.out_messages = out_messages
199 | self.decoded = decoded
200 | self.account = account
201 | }
202 | }
203 |
204 | public struct TSDKParamsOfRunGet: Codable, @unchecked Sendable {
205 | /// Account BOC in `base64`
206 | public var account: String
207 | /// Function name
208 | public var function_name: String
209 | /// Input parameters
210 | public var input: AnyValue?
211 | /// Execution options
212 | public var execution_options: TSDKExecutionOptions?
213 | /// Convert lists based on nested tuples in the **result** into plain arrays.
214 | /// Default is `false`. Input parameters may use any of lists representationsIf you receive this error on Web: "Runtime error. Unreachable code should not be executed...",set this flag to true.
215 | /// This may happen, for example, when elector contract contains too many participants
216 | public var tuple_list_as_array: Bool?
217 |
218 | public init(account: String, function_name: String, input: AnyValue? = nil, execution_options: TSDKExecutionOptions? = nil, tuple_list_as_array: Bool? = nil) {
219 | self.account = account
220 | self.function_name = function_name
221 | self.input = input
222 | self.execution_options = execution_options
223 | self.tuple_list_as_array = tuple_list_as_array
224 | }
225 | }
226 |
227 | public struct TSDKResultOfRunGet: Codable, @unchecked Sendable {
228 | /// Values returned by get-method on stack
229 | public var output: AnyValue
230 |
231 | public init(output: AnyValue) {
232 | self.output = output
233 | }
234 | }
235 |
236 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Utils/Utils.swift:
--------------------------------------------------------------------------------
1 | public final class TSDKUtilsModule {
2 |
3 | private var binding: TSDKBindingModule
4 | public let module: String = "utils"
5 |
6 | public init(binding: TSDKBindingModule) {
7 | self.binding = binding
8 | }
9 |
10 | /// Converts address from any TON format to any TON format
11 | public func convert_address(_ payload: TSDKParamsOfConvertAddress, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
12 | ) throws {
13 | let method: String = "convert_address"
14 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
15 | var response: TSDKBindingResponse = .init()
16 | response.update(requestId, params, responseType, finished)
17 | try handler(response)
18 | }
19 | }
20 |
21 | /// Converts address from any TON format to any TON format
22 | @available(iOS 13, *)
23 | @available(macOS 12, *)
24 | public func convert_address(_ payload: TSDKParamsOfConvertAddress) async throws -> TSDKResultOfConvertAddress {
25 | try await withCheckedThrowingContinuation { continuation in
26 | do {
27 | let method: String = "convert_address"
28 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
29 | var response: TSDKBindingResponse = .init()
30 | response.update(requestId, params, responseType, finished)
31 | if let error = response.error {
32 | continuation.resume(throwing: error)
33 | } else if let result = response.result {
34 | continuation.resume(returning: result)
35 | } else {
36 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
37 | }
38 | }
39 | } catch {
40 | continuation.resume(throwing: error)
41 | }
42 | }
43 | }
44 |
45 | /// Validates and returns the type of any TON address.
46 | /// Address types are the following`0:919db8e740d50bf349df2eea03fa30c385d846b991ff5542e67098ee833fc7f7` - standard TON address mostcommonly used in all cases. Also called as hex address`919db8e740d50bf349df2eea03fa30c385d846b991ff5542e67098ee833fc7f7` - account ID. A part of fulladdress. Identifies account inside particular workchain`EQCRnbjnQNUL80nfLuoD+jDDhdhGuZH/VULmcJjugz/H9wam` - base64 address. Also called "user-friendly".
47 | /// Was used at the beginning of TON. Now it is supported for compatibility
48 | public func get_address_type(_ payload: TSDKParamsOfGetAddressType, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
49 | ) throws {
50 | let method: String = "get_address_type"
51 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
52 | var response: TSDKBindingResponse = .init()
53 | response.update(requestId, params, responseType, finished)
54 | try handler(response)
55 | }
56 | }
57 |
58 | /// Validates and returns the type of any TON address.
59 | /// Address types are the following`0:919db8e740d50bf349df2eea03fa30c385d846b991ff5542e67098ee833fc7f7` - standard TON address mostcommonly used in all cases. Also called as hex address`919db8e740d50bf349df2eea03fa30c385d846b991ff5542e67098ee833fc7f7` - account ID. A part of fulladdress. Identifies account inside particular workchain`EQCRnbjnQNUL80nfLuoD+jDDhdhGuZH/VULmcJjugz/H9wam` - base64 address. Also called "user-friendly".
60 | /// Was used at the beginning of TON. Now it is supported for compatibility
61 | @available(iOS 13, *)
62 | @available(macOS 12, *)
63 | public func get_address_type(_ payload: TSDKParamsOfGetAddressType) async throws -> TSDKResultOfGetAddressType {
64 | try await withCheckedThrowingContinuation { continuation in
65 | do {
66 | let method: String = "get_address_type"
67 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
68 | var response: TSDKBindingResponse = .init()
69 | response.update(requestId, params, responseType, finished)
70 | if let error = response.error {
71 | continuation.resume(throwing: error)
72 | } else if let result = response.result {
73 | continuation.resume(returning: result)
74 | } else {
75 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
76 | }
77 | }
78 | } catch {
79 | continuation.resume(throwing: error)
80 | }
81 | }
82 | }
83 |
84 | /// Calculates storage fee for an account over a specified time period
85 | public func calc_storage_fee(_ payload: TSDKParamsOfCalcStorageFee, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
86 | ) throws {
87 | let method: String = "calc_storage_fee"
88 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
89 | var response: TSDKBindingResponse = .init()
90 | response.update(requestId, params, responseType, finished)
91 | try handler(response)
92 | }
93 | }
94 |
95 | /// Calculates storage fee for an account over a specified time period
96 | @available(iOS 13, *)
97 | @available(macOS 12, *)
98 | public func calc_storage_fee(_ payload: TSDKParamsOfCalcStorageFee) async throws -> TSDKResultOfCalcStorageFee {
99 | try await withCheckedThrowingContinuation { continuation in
100 | do {
101 | let method: String = "calc_storage_fee"
102 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
103 | var response: TSDKBindingResponse = .init()
104 | response.update(requestId, params, responseType, finished)
105 | if let error = response.error {
106 | continuation.resume(throwing: error)
107 | } else if let result = response.result {
108 | continuation.resume(returning: result)
109 | } else {
110 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
111 | }
112 | }
113 | } catch {
114 | continuation.resume(throwing: error)
115 | }
116 | }
117 | }
118 |
119 | /// Compresses data using Zstandard algorithm
120 | public func compress_zstd(_ payload: TSDKParamsOfCompressZstd, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
121 | ) throws {
122 | let method: String = "compress_zstd"
123 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
124 | var response: TSDKBindingResponse = .init()
125 | response.update(requestId, params, responseType, finished)
126 | try handler(response)
127 | }
128 | }
129 |
130 | /// Compresses data using Zstandard algorithm
131 | @available(iOS 13, *)
132 | @available(macOS 12, *)
133 | public func compress_zstd(_ payload: TSDKParamsOfCompressZstd) async throws -> TSDKResultOfCompressZstd {
134 | try await withCheckedThrowingContinuation { continuation in
135 | do {
136 | let method: String = "compress_zstd"
137 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
138 | var response: TSDKBindingResponse = .init()
139 | response.update(requestId, params, responseType, finished)
140 | if let error = response.error {
141 | continuation.resume(throwing: error)
142 | } else if let result = response.result {
143 | continuation.resume(returning: result)
144 | } else {
145 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
146 | }
147 | }
148 | } catch {
149 | continuation.resume(throwing: error)
150 | }
151 | }
152 | }
153 |
154 | /// Decompresses data using Zstandard algorithm
155 | public func decompress_zstd(_ payload: TSDKParamsOfDecompressZstd, _ handler: @escaping @Sendable (TSDKBindingResponse) throws -> Void
156 | ) throws {
157 | let method: String = "decompress_zstd"
158 | try binding.requestLibraryAsync(methodName(module, method), payload) { (requestId, params, responseType, finished) in
159 | var response: TSDKBindingResponse = .init()
160 | response.update(requestId, params, responseType, finished)
161 | try handler(response)
162 | }
163 | }
164 |
165 | /// Decompresses data using Zstandard algorithm
166 | @available(iOS 13, *)
167 | @available(macOS 12, *)
168 | public func decompress_zstd(_ payload: TSDKParamsOfDecompressZstd) async throws -> TSDKResultOfDecompressZstd {
169 | try await withCheckedThrowingContinuation { continuation in
170 | do {
171 | let method: String = "decompress_zstd"
172 | try binding.requestLibraryAsyncAwait(methodName(module, method), payload) { (requestId, params, responseType, finished) in
173 | var response: TSDKBindingResponse = .init()
174 | response.update(requestId, params, responseType, finished)
175 | if let error = response.error {
176 | continuation.resume(throwing: error)
177 | } else if let result = response.result {
178 | continuation.resume(returning: result)
179 | } else {
180 | continuation.resume(throwing: TSDKClientError("Nothing for return"))
181 | }
182 | }
183 | } catch {
184 | continuation.resume(throwing: error)
185 | }
186 | }
187 | }
188 |
189 | }
190 |
--------------------------------------------------------------------------------
/Sources/EverscaleClientSwift/Utils/UtilsTypes.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 | import SwiftExtensionsPack
3 |
4 |
5 | public enum TSDKAddressStringFormatEnumTypes: String, Codable {
6 | case AccountId = "AccountId"
7 | case Hex = "Hex"
8 | case Base64 = "Base64"
9 | }
10 |
11 | public enum TSDKAccountAddressType: String, Codable {
12 | case AccountId = "AccountId"
13 | case Hex = "Hex"
14 | case Base64 = "Base64"
15 | }
16 |
17 | public struct TSDKAddressStringFormat: Codable, @unchecked Sendable {
18 | public var type: TSDKAddressStringFormatEnumTypes
19 | public var url: Bool?
20 | public var test: Bool?
21 | public var bounce: Bool?
22 |
23 | public init(type: TSDKAddressStringFormatEnumTypes, url: Bool? = nil, test: Bool? = nil, bounce: Bool? = nil) {
24 | self.type = type
25 | self.url = url
26 | self.test = test
27 | self.bounce = bounce
28 | }
29 | }
30 |
31 | public struct TSDKParamsOfConvertAddress: Codable, @unchecked Sendable {
32 | /// Account address in any TON format.
33 | public var address: String
34 | /// Specify the format to convert to.
35 | public var output_format: TSDKAddressStringFormat
36 |
37 | public init(address: String, output_format: TSDKAddressStringFormat) {
38 | self.address = address
39 | self.output_format = output_format
40 | }
41 | }
42 |
43 | public struct TSDKResultOfConvertAddress: Codable, @unchecked Sendable {
44 | /// Address in the specified format
45 | public var address: String
46 |
47 | public init(address: String) {
48 | self.address = address
49 | }
50 | }
51 |
52 | public struct TSDKParamsOfGetAddressType: Codable, @unchecked Sendable {
53 | /// Account address in any TON format.
54 | public var address: String
55 |
56 | public init(address: String) {
57 | self.address = address
58 | }
59 | }
60 |
61 | public struct TSDKResultOfGetAddressType: Codable, @unchecked Sendable {
62 | /// Account address type.
63 | public var address_type: TSDKAccountAddressType
64 |
65 | public init(address_type: TSDKAccountAddressType) {
66 | self.address_type = address_type
67 | }
68 | }
69 |
70 | public struct TSDKParamsOfCalcStorageFee: Codable, @unchecked Sendable {
71 | public var account: String
72 | public var period: UInt32
73 |
74 | public init(account: String, period: UInt32) {
75 | self.account = account
76 | self.period = period
77 | }
78 | }
79 |
80 | public struct TSDKResultOfCalcStorageFee: Codable, @unchecked Sendable {
81 | public var fee: String
82 |
83 | public init(fee: String) {
84 | self.fee = fee
85 | }
86 | }
87 |
88 | public struct TSDKParamsOfCompressZstd: Codable, @unchecked Sendable {
89 | /// Uncompressed data.
90 | /// Must be encoded as base64.
91 | public var uncompressed: String
92 | /// Compression level, from 1 to 21. Where: 1 - lowest compression level (fastest compression); 21 - highest compression level (slowest compression). If level is omitted, the default compression level is used (currently `3`).
93 | public var level: Int32?
94 |
95 | public init(uncompressed: String, level: Int32? = nil) {
96 | self.uncompressed = uncompressed
97 | self.level = level
98 | }
99 | }
100 |
101 | public struct TSDKResultOfCompressZstd: Codable, @unchecked Sendable {
102 | /// Compressed data.
103 | /// Must be encoded as base64.
104 | public var compressed: String
105 |
106 | public init(compressed: String) {
107 | self.compressed = compressed
108 | }
109 | }
110 |
111 | public struct TSDKParamsOfDecompressZstd: Codable, @unchecked Sendable {
112 | /// Compressed data.
113 | /// Must be encoded as base64.
114 | public var compressed: String
115 |
116 | public init(compressed: String) {
117 | self.compressed = compressed
118 | }
119 | }
120 |
121 | public struct TSDKResultOfDecompressZstd: Codable, @unchecked Sendable {
122 | /// Decompressed data.
123 | /// Must be encoded as base64.
124 | public var decompressed: String
125 |
126 | public init(decompressed: String) {
127 | self.decompressed = decompressed
128 | }
129 | }
130 |
131 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/BindingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Created by Oleh Hudeichuk on 18.10.2020.
3 | //
4 |
5 | import XCTest
6 | import class Foundation.Bundle
7 | @testable import EverscaleClientSwift
8 | @testable import CTonSDK
9 | @testable import SwiftExtensionsPack
10 |
11 | final class BindingTests: XCTestCase {
12 |
13 | func testConvertToTSDKString() throws {
14 | var string: tc_string_data_t!
15 | try TSDKBindingModule.convertToTSDKString("Hello😀") { tsdkString in
16 | string = tsdkString
17 | }
18 | XCTAssertEqual(string.len, 9)
19 | }
20 |
21 | func testConvertFromTSDKString() throws {
22 | var swiftString: String = .init()
23 | try TSDKBindingModule.convertToTSDKString("Hello😀") { tsdkString in
24 | swiftString = try TSDKBindingModule.convertFromTSDKString(tsdkString)
25 | }
26 | XCTAssertEqual(swiftString, "Hello😀")
27 | }
28 |
29 | struct Test: Codable {
30 | var version: String
31 | }
32 |
33 | struct TestError: Codable {
34 | var code: UInt32
35 | var message: String
36 | var data: AnyValue
37 | }
38 |
39 | func testRequestLibraryAsync() throws {
40 | let binding: TSDKBindingModule = try .init()
41 | for _ in 1...500 {
42 | try binding.requestLibraryAsync("client.version", "{}") { (requestId, params, responseType, finished) in
43 | var response: TSDKBindingResponse = .init()
44 | response.update(requestId, params, responseType, finished)
45 | XCTAssertTrue(response.result?.version != nil)
46 | XCTAssertEqual(response.error?.message, nil)
47 | }
48 | }
49 | usleep(500000)
50 | }
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/ClientTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 19.11.2020.
6 | //
7 |
8 | import XCTest
9 | import class Foundation.Bundle
10 | @testable import EverscaleClientSwift
11 | @testable import CTonSDK
12 |
13 | final class ClientTests: XCTestCase {
14 |
15 | func testGet_api_reference() throws {
16 | try testAsyncMethods { (client, group) in
17 | group.enter()
18 | try client.get_api_reference { (response) in
19 | XCTAssertTrue(response.result?.api != nil)
20 | group.leave()
21 | }
22 | group.wait()
23 | }
24 | }
25 |
26 | func testVersion() throws {
27 | try testAsyncMethods { (client, group) in
28 | group.enter()
29 | try client.version { (response) in
30 | XCTAssertTrue(response.result?.version != nil)
31 | if response.finished {
32 | group.leave()
33 | }
34 | }
35 | group.wait()
36 | }
37 | }
38 |
39 | func testBuild_info() throws {
40 | try testAsyncMethods { (client, group) in
41 | group.enter()
42 | try client.build_info { (response) in
43 | XCTAssertTrue(response.result?.build_number != nil)
44 | if response.finished {
45 | group.leave()
46 | }
47 | }
48 | group.wait()
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/ErrorsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ErrorsTests.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 17.09.2022.
6 | //
7 |
8 | import XCTest
9 | import class Foundation.Bundle
10 | @testable import EverscaleClientSwift
11 | @testable import CTonSDK
12 |
13 | final class ErrorsTests: XCTestCase {
14 |
15 | func testClientError() throws {
16 | try testAsyncMethods { (client, group) in
17 | let paramsOfQueryCollection: TSDKParamsOfQueryCollection = .init(collection: "accounts",
18 | filter: [
19 | "id": [
20 | "eq": "0:b5e9240fc2d2f1ff8cbb1d1dee7fb7cae155e5f6320e585fcc685698994a19a5"
21 | ]
22 | ].toAnyValue(),
23 | result: "boc")
24 | group.enter()
25 | do {
26 | try client.net.query_collection(paramsOfQueryCollection) { [group] response in
27 | if response.error != nil {
28 | group.leave()
29 | } else {
30 | throw TSDKClientError("FATAL ERROR")
31 | }
32 | }
33 | } catch {
34 | group.leave()
35 | }
36 | group.wait()
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Events.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "emitValue",
7 | "inputs": [
8 | {"name":"id","type":"uint256"}
9 | ],
10 | "outputs": [
11 | ]
12 | },
13 | {
14 | "name": "returnValue",
15 | "inputs": [
16 | {"name":"id","type":"uint256"}
17 | ],
18 | "outputs": [
19 | {"name":"value0","type":"uint256"}
20 | ]
21 | },
22 | {
23 | "name": "sendAllMoney",
24 | "inputs": [
25 | {"name":"dest_addr","type":"address"}
26 | ],
27 | "outputs": [
28 | ]
29 | },
30 | {
31 | "name": "constructor",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | ]
36 | }
37 | ],
38 | "data": [
39 | ],
40 | "events": [
41 | {
42 | "name": "EventThrown",
43 | "inputs": [
44 | {"name":"id","type":"uint256"}
45 | ],
46 | "outputs": [
47 | ]
48 | }
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Events.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/Events.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Giver.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["time"],
4 | "functions": [
5 | {
6 | "name": "grant",
7 | "inputs": [
8 | {"name":"addr","type":"address"}
9 | ],
10 | "outputs": [
11 | ]
12 | },
13 | {
14 | "name": "constructor",
15 | "inputs": [
16 | ],
17 | "outputs": [
18 | ]
19 | }
20 | ],
21 | "data": [
22 | ],
23 | "events": [
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/GiverNodeSE.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 1,
3 | "functions": [
4 | {
5 | "name": "constructor",
6 | "inputs": [],
7 | "outputs": []
8 | },
9 | {
10 | "name": "sendGrams",
11 | "inputs": [
12 | {"name": "dest", "type": "address"},
13 | {"name": "amount", "type": "uint64"}
14 | ],
15 | "outputs": []
16 | }
17 | ],
18 | "events": [],
19 | "data": []
20 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/GiverNodeSE_v2.abi.json:
--------------------------------------------------------------------------------
1 | {"ABI version": 2,
2 | "header": ["time", "expire"],
3 | "functions": [
4 | {
5 | "name": "upgrade",
6 | "inputs": [
7 | {"name":"newcode","type":"cell"}
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "sendTransaction",
14 | "inputs": [
15 | {"name":"dest","type":"address"},
16 | {"name":"value","type":"uint128"},
17 | {"name":"bounce","type":"bool"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "getMessages",
24 | "inputs": [
25 | ],
26 | "outputs": [
27 | {"components":[{"name":"hash","type":"uint256"},{"name":"expireAt","type":"uint64"}],"name":"messages","type":"tuple[]"}
28 | ]
29 | },
30 | {
31 | "name": "constructor",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | ]
36 | }
37 | ],
38 | "events": [
39 | ]
40 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/GiverNodeSE_v2.keys.json:
--------------------------------------------------------------------------------
1 | {
2 | "public": "2ada2e65ab8eeab09490e3521415f45b6e42df9c760a639bcf53957550b25a16",
3 | "secret": "172af540e43a524763dd53b26a066d472a97c4de37d5498170564510608250c3"
4 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/GiverV2.abi.json:
--------------------------------------------------------------------------------
1 | {"ABI version": 2,
2 | "header": ["time", "expire"],
3 | "functions": [
4 | {
5 | "name": "upgrade",
6 | "inputs": [
7 | {"name":"newcode","type":"cell"}
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "sendTransaction",
14 | "inputs": [
15 | {"name":"dest","type":"address"},
16 | {"name":"value","type":"uint128"},
17 | {"name":"bounce","type":"bool"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "getMessages",
24 | "inputs": [
25 | ],
26 | "outputs": [
27 | {"components":[{"name":"hash","type":"uint256"},{"name":"expireAt","type":"uint64"}],"name":"messages","type":"tuple[]"}
28 | ]
29 | },
30 | {
31 | "name": "constructor",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | ]
36 | }
37 | ],
38 | "events": [
39 | ]
40 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/GiverV2.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/GiverV2.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/GiverWallet.abi.json:
--------------------------------------------------------------------------------
1 | {"ABI version": 2,
2 | "header": ["time", "expire"],
3 | "functions": [
4 | {
5 | "name": "upgrade",
6 | "inputs": [
7 | {"name":"newcode","type":"cell"}
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "sendTransaction",
14 | "inputs": [
15 | {"name":"dest","type":"address"},
16 | {"name":"value","type":"uint128"},
17 | {"name":"bounce","type":"bool"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "getMessages",
24 | "inputs": [
25 | ],
26 | "outputs": [
27 | {"components":[{"name":"hash","type":"uint256"},{"name":"expireAt","type":"uint64"}],"name":"messages","type":"tuple[]"}
28 | ]
29 | },
30 | {
31 | "name": "constructor",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | ]
36 | }
37 | ],
38 | "events": [
39 | ]
40 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Hello.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "touch",
14 | "inputs": [
15 | ],
16 | "outputs": [
17 | ]
18 | },
19 | {
20 | "name": "sayHello",
21 | "inputs": [
22 | ],
23 | "outputs": [
24 | {"name":"value0","type":"uint32"}
25 | ]
26 | },
27 | {
28 | "name": "sendAllMoney",
29 | "inputs": [
30 | {"name":"dest_addr","type":"address"}
31 | ],
32 | "outputs": [
33 | ]
34 | }
35 | ],
36 | "events": [
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Hello.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/Hello.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/LimitWallet.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["time", "expire"],
4 | "functions": [
5 | {
6 | "name": "sendTransaction",
7 | "inputs": [
8 | {"name":"dest","type":"address"},
9 | {"name":"value","type":"uint128"},
10 | {"name":"bounce","type":"bool"}
11 | ],
12 | "outputs": [
13 | ]
14 | },
15 | {
16 | "name": "fallback",
17 | "inputs": [
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "setSubscriptionAccount",
24 | "inputs": [
25 | {"name":"addr","type":"address"}
26 | ],
27 | "outputs": [
28 | ]
29 | },
30 | {
31 | "name": "getSubscriptionAccount",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | {"name":"value0","type":"address"}
36 | ]
37 | },
38 | {
39 | "name": "createOperationLimit",
40 | "inputs": [
41 | {"name":"value","type":"uint256"}
42 | ],
43 | "outputs": [
44 | {"name":"value0","type":"uint256"}
45 | ]
46 | },
47 | {
48 | "name": "createArbitraryLimit",
49 | "inputs": [
50 | {"name":"value","type":"uint256"},
51 | {"name":"period","type":"uint32"}
52 | ],
53 | "outputs": [
54 | {"name":"value0","type":"uint64"}
55 | ]
56 | },
57 | {
58 | "name": "changeLimit",
59 | "inputs": [
60 | {"name":"limitId","type":"uint64"},
61 | {"name":"value","type":"uint256"},
62 | {"name":"period","type":"uint32"}
63 | ],
64 | "outputs": [
65 | ]
66 | },
67 | {
68 | "name": "deleteLimit",
69 | "inputs": [
70 | {"name":"limitId","type":"uint64"}
71 | ],
72 | "outputs": [
73 | ]
74 | },
75 | {
76 | "name": "getLimit",
77 | "inputs": [
78 | {"name":"limitId","type":"uint64"}
79 | ],
80 | "outputs": [
81 | {"components":[{"name":"value","type":"uint256"},{"name":"period","type":"uint32"},{"name":"ltype","type":"uint8"},{"name":"spent","type":"uint256"},{"name":"start","type":"uint32"}],"name":"value0","type":"tuple"}
82 | ]
83 | },
84 | {
85 | "name": "getLimitCount",
86 | "inputs": [
87 | ],
88 | "outputs": [
89 | {"name":"value0","type":"uint64"}
90 | ]
91 | },
92 | {
93 | "name": "getLimits",
94 | "inputs": [
95 | ],
96 | "outputs": [
97 | {"components":[{"name":"value","type":"uint256"},{"name":"period","type":"uint32"},{"name":"ltype","type":"uint8"},{"name":"spent","type":"uint256"},{"name":"start","type":"uint32"}],"name":"limits","type":"tuple[]"}
98 | ]
99 | },
100 | {
101 | "name": "constructor",
102 | "inputs": [
103 | ],
104 | "outputs": [
105 | ]
106 | }
107 | ],
108 | "events": [
109 | ]
110 | }
111 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/LimitWallet.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/LimitWallet.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Piggy.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"amount","type":"uint64"},
9 | {"name":"goal","type":"bytes"}
10 | ],
11 | "outputs": [
12 | ]
13 | },
14 | {
15 | "name": "transfer",
16 | "inputs": [
17 | {"name":"to","type":"address"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "getGoal",
24 | "inputs": [
25 | ],
26 | "outputs": [
27 | {"name":"value0","type":"bytes"}
28 | ]
29 | },
30 | {
31 | "name": "getTargetAmount",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | {"name":"value0","type":"uint64"}
36 | ]
37 | },
38 | {
39 | "name": "fallback",
40 | "inputs": [
41 | ],
42 | "outputs": [
43 | ]
44 | }
45 | ],
46 | "events": [
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Piggy.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/Piggy.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/SetcodeMultisigWallet2.abi.json:
--------------------------------------------------------------------------------
1 | {
"ABI version": 2,
"header": ["pubkey", "time", "expire"],
"functions": [
{
"name": "constructor",
"inputs": [
{"name":"owners","type":"uint256[]"},
{"name":"reqConfirms","type":"uint8"}
],
"outputs": [
]
},
{
"name": "acceptTransfer",
"inputs": [
{"name":"payload","type":"bytes"}
],
"outputs": [
]
},
{
"name": "sendTransaction",
"inputs": [
{"name":"dest","type":"address"},
{"name":"value","type":"uint128"},
{"name":"bounce","type":"bool"},
{"name":"flags","type":"uint8"},
{"name":"payload","type":"cell"}
],
"outputs": [
]
},
{
"name": "submitTransaction",
"inputs": [
{"name":"dest","type":"address"},
{"name":"value","type":"uint128"},
{"name":"bounce","type":"bool"},
{"name":"allBalance","type":"bool"},
{"name":"payload","type":"cell"}
],
"outputs": [
{"name":"transId","type":"uint64"}
]
},
{
"name": "confirmTransaction",
"inputs": [
{"name":"transactionId","type":"uint64"}
],
"outputs": [
]
},
{
"name": "isConfirmed",
"inputs": [
{"name":"mask","type":"uint32"},
{"name":"index","type":"uint8"}
],
"outputs": [
{"name":"confirmed","type":"bool"}
]
},
{
"name": "getParameters",
"inputs": [
],
"outputs": [
{"name":"maxQueuedTransactions","type":"uint8"},
{"name":"maxCustodianCount","type":"uint8"},
{"name":"expirationTime","type":"uint64"},
{"name":"minValue","type":"uint128"},
{"name":"requiredTxnConfirms","type":"uint8"},
{"name":"requiredUpdConfirms","type":"uint8"}
]
},
{
"name": "getTransaction",
"inputs": [
{"name":"transactionId","type":"uint64"}
],
"outputs": [
{"components":[{"name":"id","type":"uint64"},{"name":"confirmationsMask","type":"uint32"},{"name":"signsRequired","type":"uint8"},{"name":"signsReceived","type":"uint8"},{"name":"creator","type":"uint256"},{"name":"index","type":"uint8"},{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"sendFlags","type":"uint16"},{"name":"payload","type":"cell"},{"name":"bounce","type":"bool"}],"name":"trans","type":"tuple"}
]
},
{
"name": "getTransactions",
"inputs": [
],
"outputs": [
{"components":[{"name":"id","type":"uint64"},{"name":"confirmationsMask","type":"uint32"},{"name":"signsRequired","type":"uint8"},{"name":"signsReceived","type":"uint8"},{"name":"creator","type":"uint256"},{"name":"index","type":"uint8"},{"name":"dest","type":"address"},{"name":"value","type":"uint128"},{"name":"sendFlags","type":"uint16"},{"name":"payload","type":"cell"},{"name":"bounce","type":"bool"}],"name":"transactions","type":"tuple[]"}
]
},
{
"name": "getTransactionIds",
"inputs": [
],
"outputs": [
{"name":"ids","type":"uint64[]"}
]
},
{
"name": "getCustodians",
"inputs": [
],
"outputs": [
{"components":[{"name":"index","type":"uint8"},{"name":"pubkey","type":"uint256"}],"name":"custodians","type":"tuple[]"}
]
},
{
"name": "submitUpdate",
"inputs": [
{"name":"codeHash","type":"uint256"},
{"name":"owners","type":"uint256[]"},
{"name":"reqConfirms","type":"uint8"}
],
"outputs": [
{"name":"updateId","type":"uint64"}
]
},
{
"name": "confirmUpdate",
"inputs": [
{"name":"updateId","type":"uint64"}
],
"outputs": [
]
},
{
"name": "executeUpdate",
"inputs": [
{"name":"updateId","type":"uint64"},
{"name":"code","type":"cell"}
],
"outputs": [
]
},
{
"name": "getUpdateRequests",
"inputs": [
],
"outputs": [
{"components":[{"name":"id","type":"uint64"},{"name":"index","type":"uint8"},{"name":"signs","type":"uint8"},{"name":"confirmationsMask","type":"uint32"},{"name":"creator","type":"uint256"},{"name":"codeHash","type":"uint256"},{"name":"custodians","type":"uint256[]"},{"name":"reqConfirms","type":"uint8"}],"name":"updates","type":"tuple[]"}
]
}
],
"data": [
],
"events": [
{
"name": "TransferAccepted",
"inputs": [
{"name":"payload","type":"bytes"}
],
"outputs": [
]
}
]
}
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/SetcodeMultisigWallet2.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/SetcodeMultisigWallet2.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Subscription.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"wallet","type":"address"}
9 | ],
10 | "outputs": [
11 | ]
12 | },
13 | {
14 | "name": "getWallet",
15 | "inputs": [
16 | ],
17 | "outputs": [
18 | {"name":"value0","type":"address"}
19 | ]
20 | },
21 | {
22 | "name": "getSubscription",
23 | "inputs": [
24 | {"name":"subscriptionId","type":"uint256"}
25 | ],
26 | "outputs": [
27 | {"components":[{"name":"pubkey","type":"uint256"},{"name":"to","type":"address"},{"name":"value","type":"uint64"},{"name":"period","type":"uint32"},{"name":"start","type":"uint32"},{"name":"status","type":"uint8"}],"name":"value0","type":"tuple"}
28 | ]
29 | },
30 | {
31 | "name": "subscribe",
32 | "inputs": [
33 | {"name":"subscriptionId","type":"uint256"},
34 | {"name":"pubkey","type":"uint256"},
35 | {"name":"to","type":"address"},
36 | {"name":"value","type":"uint64"},
37 | {"name":"period","type":"uint32"}
38 | ],
39 | "outputs": [
40 | ]
41 | },
42 | {
43 | "name": "cancel",
44 | "inputs": [
45 | {"name":"subscriptionId","type":"uint256"}
46 | ],
47 | "outputs": [
48 | ]
49 | },
50 | {
51 | "name": "executeSubscription",
52 | "inputs": [
53 | {"name":"subscriptionId","type":"uint256"}
54 | ],
55 | "outputs": [
56 | ]
57 | },
58 | {
59 | "name": "sendAllMoney",
60 | "inputs": [
61 | {"name":"dest_addr","type":"address"}
62 | ],
63 | "outputs": [
64 | ]
65 | }
66 | ],
67 | "events": [
68 | ]
69 | }
70 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Subscription.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/Subscription.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Wallet.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "sendTransaction",
14 | "inputs": [
15 | {"name":"dest","type":"address"},
16 | {"name":"value","type":"uint128"},
17 | {"name":"bounce","type":"bool"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "sendAllMoney",
24 | "inputs": [
25 | {"name":"dest_addr","type":"address"}
26 | ],
27 | "outputs": [
28 | ]
29 | }
30 | ],
31 | "events": [
32 | ]
33 | }
34 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/Wallet.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/Wallet.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/helloDebot.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "setIcon",
7 | "inputs": [
8 | {"name":"icon","type":"bytes"}
9 | ],
10 | "outputs": [
11 | ]
12 | },
13 | {
14 | "name": "start",
15 | "inputs": [
16 | ],
17 | "outputs": [
18 | ]
19 | },
20 | {
21 | "name": "getDebotInfo",
22 | "id": "0xDEB",
23 | "inputs": [
24 | ],
25 | "outputs": [
26 | {"name":"name","type":"bytes"},
27 | {"name":"version","type":"bytes"},
28 | {"name":"publisher","type":"bytes"},
29 | {"name":"caption","type":"bytes"},
30 | {"name":"author","type":"bytes"},
31 | {"name":"support","type":"address"},
32 | {"name":"hello","type":"bytes"},
33 | {"name":"language","type":"bytes"},
34 | {"name":"dabi","type":"bytes"},
35 | {"name":"icon","type":"bytes"}
36 | ]
37 | },
38 | {
39 | "name": "getRequiredInterfaces",
40 | "inputs": [
41 | ],
42 | "outputs": [
43 | {"name":"interfaces","type":"uint256[]"}
44 | ]
45 | },
46 | {
47 | "name": "setUserInput",
48 | "inputs": [
49 | {"name":"value","type":"bytes"}
50 | ],
51 | "outputs": [
52 | ]
53 | },
54 | {
55 | "name": "getDebotOptions",
56 | "inputs": [
57 | ],
58 | "outputs": [
59 | {"name":"options","type":"uint8"},
60 | {"name":"debotAbi","type":"bytes"},
61 | {"name":"targetAbi","type":"bytes"},
62 | {"name":"targetAddr","type":"address"}
63 | ]
64 | },
65 | {
66 | "name": "setABI",
67 | "inputs": [
68 | {"name":"dabi","type":"bytes"}
69 | ],
70 | "outputs": [
71 | ]
72 | },
73 | {
74 | "name": "constructor",
75 | "inputs": [
76 | ],
77 | "outputs": [
78 | ]
79 | }
80 | ],
81 | "data": [
82 | ],
83 | "events": [
84 | ]
85 | }
86 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/helloDebot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/helloDebot.png
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/helloDebot.sol:
--------------------------------------------------------------------------------
1 | pragma ton-solidity >=0.35.0;
2 | pragma AbiHeader expire;
3 | pragma AbiHeader time;
4 | pragma AbiHeader pubkey;
5 | // import required DeBot interfaces and basic DeBot contract.
6 | import "../Debot.sol";
7 | import "../Terminal.sol";
8 |
9 | contract HelloDebot is Debot {
10 | bytes m_icon;
11 |
12 | function setIcon(bytes icon) public {
13 | require(msg.pubkey() == tvm.pubkey(), 100);
14 | tvm.accept();
15 | m_icon = icon;
16 | }
17 |
18 | /// @notice Entry point function for DeBot.
19 | function start() public override {
20 | // print string to user.
21 | Terminal.print(0, "Hello, World!");
22 | // input string from user and define callback that receives entered string.
23 | Terminal.input(tvm.functionId(setUserInput), "How is it going?", false);
24 | }
25 |
26 | /// @notice Returns Metadata about DeBot.
27 | function getDebotInfo() public functionID(0xDEB) override view returns(
28 | string name, string version, string publisher, string caption, string author,
29 | address support, string hello, string language, string dabi, bytes icon
30 | ) {
31 | name = "HelloWorld";
32 | version = "0.2.0";
33 | publisher = "TON Labs";
34 | caption = "Start develop DeBot from here";
35 | author = "TON Labs";
36 | support = address.makeAddrStd(0, 0x841288ed3b55d9cdafa806807f02a0ae0c169aa5edfe88a789a6482429756a94);
37 | hello = "Hello, i am a HelloWorld DeBot.";
38 | language = "en";
39 | dabi = m_debotAbi.get();
40 | icon = m_icon;
41 | }
42 |
43 | function getRequiredInterfaces() public view override returns (uint256[] interfaces) {
44 | return [ Terminal.ID ];
45 | }
46 |
47 | function setUserInput(string value) public {
48 | // TODO: continue DeBot logic here...
49 | Terminal.print(0, format("You have entered \"{}\"", value));
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/helloDebot.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/helloDebot.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/tda.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"targetAddr","type":"address"}
9 | ],
10 | "outputs": [
11 | ]
12 | },
13 | {
14 | "name": "setAbi",
15 | "inputs": [
16 | {"name":"debotAbi","type":"bytes"}
17 | ],
18 | "outputs": [
19 | ]
20 | },
21 | {
22 | "name": "start",
23 | "inputs": [
24 | ],
25 | "outputs": [
26 | ]
27 | },
28 | {
29 | "name": "getVersion",
30 | "inputs": [
31 | ],
32 | "outputs": [
33 | {"name":"name","type":"bytes"},
34 | {"name":"semver","type":"uint24"}
35 | ]
36 | },
37 | {
38 | "name": "onResponse",
39 | "inputs": [
40 | {"name":"value","type":"bytes"}
41 | ],
42 | "outputs": [
43 | ]
44 | },
45 | {
46 | "name": "fetch",
47 | "inputs": [
48 | ],
49 | "outputs": [
50 | {"components":[{"name":"id","type":"uint8"},{"name":"desc","type":"bytes"},{"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}],"name":"contexts","type":"tuple[]"}
51 | ]
52 | },
53 | {
54 | "name": "getDebotOptions",
55 | "inputs": [
56 | ],
57 | "outputs": [
58 | {"name":"options","type":"uint8"},
59 | {"name":"debotAbi","type":"bytes"},
60 | {"name":"targetAbi","type":"bytes"},
61 | {"name":"targetAddr","type":"address"}
62 | ]
63 | }
64 | ],
65 | "data": [
66 | ],
67 | "events": [
68 | ]
69 | }
70 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/tda.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/tda.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/tdb.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "setAbi",
14 | "inputs": [
15 | {"name":"debotAbi","type":"bytes"}
16 | ],
17 | "outputs": [
18 | ]
19 | },
20 | {
21 | "name": "start",
22 | "inputs": [
23 | ],
24 | "outputs": [
25 | ]
26 | },
27 | {
28 | "name": "getVersion",
29 | "inputs": [
30 | ],
31 | "outputs": [
32 | {"name":"name","type":"bytes"},
33 | {"name":"semver","type":"uint24"}
34 | ]
35 | },
36 | {
37 | "name": "onRequest",
38 | "inputs": [
39 | {"name":"request","type":"bytes"}
40 | ],
41 | "outputs": [
42 | ]
43 | },
44 | {
45 | "name": "fetch",
46 | "inputs": [
47 | ],
48 | "outputs": [
49 | {"components":[{"name":"id","type":"uint8"},{"name":"desc","type":"bytes"},{"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}],"name":"contexts","type":"tuple[]"}
50 | ]
51 | },
52 | {
53 | "name": "getDebotOptions",
54 | "inputs": [
55 | ],
56 | "outputs": [
57 | {"name":"options","type":"uint8"},
58 | {"name":"debotAbi","type":"bytes"},
59 | {"name":"targetAbi","type":"bytes"},
60 | {"name":"targetAddr","type":"address"}
61 | ]
62 | }
63 | ],
64 | "data": [
65 | ],
66 | "events": [
67 | ]
68 | }
69 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/tdb.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/tdb.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"targetAbi","type":"bytes"},
9 | {"name":"targetAddr","type":"address"}
10 | ],
11 | "outputs": [
12 | ]
13 | },
14 | {
15 | "name": "setAbi",
16 | "inputs": [
17 | {"name":"debotAbi","type":"bytes"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "fetch",
24 | "inputs": [
25 | ],
26 | "outputs": [
27 | {"components":[{"name":"id","type":"uint8"},{"name":"desc","type":"bytes"},{"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}],"name":"contexts","type":"tuple[]"}
28 | ]
29 | },
30 | {
31 | "name": "start",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | ]
36 | },
37 | {
38 | "name": "quit",
39 | "inputs": [
40 | ],
41 | "outputs": [
42 | ]
43 | },
44 | {
45 | "name": "getVersion",
46 | "inputs": [
47 | ],
48 | "outputs": [
49 | {"name":"name","type":"bytes"},
50 | {"name":"semver","type":"uint24"}
51 | ]
52 | },
53 | {
54 | "name": "getErrorDescription",
55 | "inputs": [
56 | {"name":"error","type":"uint32"}
57 | ],
58 | "outputs": [
59 | {"name":"desc","type":"bytes"}
60 | ]
61 | },
62 | {
63 | "name": "testThrowException",
64 | "inputs": [
65 | ],
66 | "outputs": [
67 | ]
68 | },
69 | {
70 | "name": "testThrowUnknownException",
71 | "inputs": [
72 | ],
73 | "outputs": [
74 | ]
75 | },
76 | {
77 | "name": "testThrowTvmException",
78 | "inputs": [
79 | ],
80 | "outputs": [
81 | ]
82 | },
83 | {
84 | "name": "setInteger",
85 | "inputs": [
86 | ],
87 | "outputs": [
88 | ]
89 | },
90 | {
91 | "name": "enterAddress",
92 | "inputs": [
93 | {"name":"addr","type":"address"}
94 | ],
95 | "outputs": [
96 | ]
97 | },
98 | {
99 | "name": "enterDebotAddress",
100 | "inputs": [
101 | {"name":"debot","type":"address"}
102 | ],
103 | "outputs": [
104 | ]
105 | },
106 | {
107 | "name": "enterString",
108 | "inputs": [
109 | {"name":"str","type":"bytes"}
110 | ],
111 | "outputs": [
112 | ]
113 | },
114 | {
115 | "name": "getPrintArgs",
116 | "inputs": [
117 | ],
118 | "outputs": [
119 | {"name":"number0","type":"int256"},
120 | {"name":"param1","type":"address"},
121 | {"name":"str2","type":"bytes"}
122 | ]
123 | },
124 | {
125 | "name": "getDataArgs",
126 | "inputs": [
127 | ],
128 | "outputs": [
129 | {"name":"number0","type":"uint256"}
130 | ]
131 | },
132 | {
133 | "name": "setData",
134 | "inputs": [
135 | {"name":"num","type":"uint256"}
136 | ],
137 | "outputs": [
138 | ]
139 | },
140 | {
141 | "name": "setData2",
142 | "inputs": [
143 | {"name":"num","type":"uint256"}
144 | ],
145 | "outputs": [
146 | ]
147 | },
148 | {
149 | "name": "getKey",
150 | "inputs": [
151 | ],
152 | "outputs": [
153 | {"name":"key","type":"uint32"}
154 | ]
155 | },
156 | {
157 | "name": "invokeDebot",
158 | "inputs": [
159 | ],
160 | "outputs": [
161 | {"name":"debot","type":"address"},
162 | {"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"action","type":"tuple"}
163 | ]
164 | },
165 | {
166 | "name": "sendSetDataMsg",
167 | "inputs": [
168 | ],
169 | "outputs": [
170 | {"name":"dest","type":"address"},
171 | {"name":"body","type":"cell"}
172 | ]
173 | },
174 | {
175 | "name": "sendTestMsg",
176 | "inputs": [
177 | ],
178 | "outputs": [
179 | {"name":"dest","type":"address"},
180 | {"name":"body","type":"cell"}
181 | ]
182 | },
183 | {
184 | "name": "setTargetAddr",
185 | "inputs": [
186 | ],
187 | "outputs": [
188 | ]
189 | },
190 | {
191 | "name": "testgenKeypairFromSecret",
192 | "inputs": [
193 | ],
194 | "outputs": [
195 | {"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}
196 | ]
197 | },
198 | {
199 | "name": "testgenRandom",
200 | "inputs": [
201 | ],
202 | "outputs": [
203 | {"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}
204 | ]
205 | },
206 | {
207 | "name": "testencryptAuth",
208 | "inputs": [
209 | ],
210 | "outputs": [
211 | {"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}
212 | ]
213 | },
214 | {
215 | "name": "testgetAccountState",
216 | "inputs": [
217 | ],
218 | "outputs": [
219 | {"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}
220 | ]
221 | },
222 | {
223 | "name": "setKeypair",
224 | "inputs": [
225 | {"name":"publicKey","type":"uint256"},
226 | {"name":"secretKey","type":"uint256"}
227 | ],
228 | "outputs": [
229 | ]
230 | },
231 | {
232 | "name": "setEncrypted",
233 | "inputs": [
234 | {"name":"encrypted","type":"bytes"}
235 | ],
236 | "outputs": [
237 | ]
238 | },
239 | {
240 | "name": "getSecret",
241 | "inputs": [
242 | ],
243 | "outputs": [
244 | {"name":"secret","type":"uint256"}
245 | ]
246 | },
247 | {
248 | "name": "getLength",
249 | "inputs": [
250 | ],
251 | "outputs": [
252 | {"name":"length","type":"uint32"}
253 | ]
254 | },
255 | {
256 | "name": "setRandom",
257 | "inputs": [
258 | {"name":"buffer","type":"bytes"}
259 | ],
260 | "outputs": [
261 | ]
262 | },
263 | {
264 | "name": "getEncryptParams",
265 | "inputs": [
266 | ],
267 | "outputs": [
268 | {"name":"decrypted","type":"bytes"},
269 | {"name":"nonce","type":"bytes"},
270 | {"name":"publicKey","type":"uint256"},
271 | {"name":"secretKey","type":"uint256"}
272 | ]
273 | },
274 | {
275 | "name": "setState",
276 | "inputs": [
277 | {"name":"balance","type":"uint256"},
278 | {"name":"acc_type","type":"int8"},
279 | {"name":"last_trans_lt","type":"uint64"},
280 | {"name":"code","type":"cell"},
281 | {"name":"data","type":"cell"},
282 | {"name":"lib","type":"cell"}
283 | ],
284 | "outputs": [
285 | ]
286 | },
287 | {
288 | "name": "testgetBalance",
289 | "inputs": [
290 | ],
291 | "outputs": [
292 | {"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}
293 | ]
294 | },
295 | {
296 | "name": "getAddr",
297 | "inputs": [
298 | ],
299 | "outputs": [
300 | {"name":"addr","type":"address"}
301 | ]
302 | },
303 | {
304 | "name": "setBalance",
305 | "inputs": [
306 | {"name":"arg1","type":"uint128"}
307 | ],
308 | "outputs": [
309 | ]
310 | },
311 | {
312 | "name": "callInterface",
313 | "inputs": [
314 | ],
315 | "outputs": [
316 | ]
317 | },
318 | {
319 | "name": "echo",
320 | "inputs": [
321 | {"name":"response","type":"bytes"}
322 | ],
323 | "outputs": [
324 | ]
325 | },
326 | {
327 | "name": "getDebotOptions",
328 | "inputs": [
329 | ],
330 | "outputs": [
331 | {"name":"options","type":"uint8"},
332 | {"name":"debotAbi","type":"bytes"},
333 | {"name":"targetAbi","type":"bytes"},
334 | {"name":"targetAddr","type":"address"}
335 | ]
336 | }
337 | ],
338 | "data": [
339 | ],
340 | "events": [
341 | ]
342 | }
343 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot2.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"pub","type":"uint256"},
9 | {"name":"sec","type":"uint256"}
10 | ],
11 | "outputs": [
12 | ]
13 | },
14 | {
15 | "name": "setAbi",
16 | "inputs": [
17 | {"name":"debotAbi","type":"bytes"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "increment",
24 | "inputs": [
25 | {"name":"value","type":"uint32"}
26 | ],
27 | "outputs": [
28 | ]
29 | },
30 | {
31 | "name": "start",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | ]
36 | },
37 | {
38 | "name": "getVersion",
39 | "inputs": [
40 | ],
41 | "outputs": [
42 | {"name":"name","type":"bytes"},
43 | {"name":"semver","type":"uint24"}
44 | ]
45 | },
46 | {
47 | "name": "callIncrement",
48 | "inputs": [
49 | ],
50 | "outputs": [
51 | ]
52 | },
53 | {
54 | "name": "onSuccess",
55 | "inputs": [
56 | ],
57 | "outputs": [
58 | ]
59 | },
60 | {
61 | "name": "onError",
62 | "inputs": [
63 | {"name":"sdkError","type":"uint32"},
64 | {"name":"exitCode","type":"uint32"}
65 | ],
66 | "outputs": [
67 | ]
68 | },
69 | {
70 | "name": "getCounter",
71 | "inputs": [
72 | ],
73 | "outputs": [
74 | ]
75 | },
76 | {
77 | "name": "setCounter",
78 | "inputs": [
79 | {"name":"counter","type":"uint32"}
80 | ],
81 | "outputs": [
82 | ]
83 | },
84 | {
85 | "name": "fetch",
86 | "inputs": [
87 | ],
88 | "outputs": [
89 | {"components":[{"name":"id","type":"uint8"},{"name":"desc","type":"bytes"},{"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}],"name":"contexts","type":"tuple[]"}
90 | ]
91 | },
92 | {
93 | "name": "getDebotOptions",
94 | "inputs": [
95 | ],
96 | "outputs": [
97 | {"name":"options","type":"uint8"},
98 | {"name":"debotAbi","type":"bytes"},
99 | {"name":"targetAbi","type":"bytes"},
100 | {"name":"targetAddr","type":"address"}
101 | ]
102 | },
103 | {
104 | "name": "counter",
105 | "inputs": [
106 | ],
107 | "outputs": [
108 | {"name":"counter","type":"uint32"}
109 | ]
110 | }
111 | ],
112 | "data": [
113 | ],
114 | "events": [
115 | ]
116 | }
117 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot2.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot2.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot3.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "start",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "getDebotInfo",
14 | "id": "0xDEB",
15 | "inputs": [
16 | ],
17 | "outputs": [
18 | {"name":"name","type":"bytes"},
19 | {"name":"version","type":"bytes"},
20 | {"name":"publisher","type":"bytes"},
21 | {"name":"caption","type":"bytes"},
22 | {"name":"author","type":"bytes"},
23 | {"name":"support","type":"address"},
24 | {"name":"hello","type":"bytes"},
25 | {"name":"language","type":"bytes"},
26 | {"name":"dabi","type":"bytes"},
27 | {"name":"icon","type":"bytes"}
28 | ]
29 | },
30 | {
31 | "name": "getRequiredInterfaces",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | {"name":"interfaces","type":"uint256[]"}
36 | ]
37 | },
38 | {
39 | "name": "runAll",
40 | "inputs": [
41 | ],
42 | "outputs": [
43 | ]
44 | },
45 | {
46 | "name": "testhdkeyXprv",
47 | "inputs": [
48 | {"name":"index","type":"uint32"}
49 | ],
50 | "outputs": [
51 | ]
52 | },
53 | {
54 | "name": "hdkeyXprvFromMnemonicRes",
55 | "inputs": [
56 | {"name":"xprv","type":"bytes"}
57 | ],
58 | "outputs": [
59 | ]
60 | },
61 | {
62 | "name": "hdkeyDeriveFromXprvRes",
63 | "inputs": [
64 | {"name":"xprv","type":"bytes"}
65 | ],
66 | "outputs": [
67 | ]
68 | },
69 | {
70 | "name": "hdkeyDeriveFromXprvPathRes",
71 | "inputs": [
72 | {"name":"xprv","type":"bytes"}
73 | ],
74 | "outputs": [
75 | ]
76 | },
77 | {
78 | "name": "hdkeySecretFromXprvRes",
79 | "inputs": [
80 | {"name":"sec","type":"uint256"}
81 | ],
82 | "outputs": [
83 | ]
84 | },
85 | {
86 | "name": "naclSignKeypairFromSecretKeyRes",
87 | "inputs": [
88 | {"name":"sec","type":"uint256"},
89 | {"name":"pub","type":"uint256"}
90 | ],
91 | "outputs": [
92 | ]
93 | },
94 | {
95 | "name": "testMnemonicDeriveSignKeys",
96 | "inputs": [
97 | {"name":"index","type":"uint32"}
98 | ],
99 | "outputs": [
100 | ]
101 | },
102 | {
103 | "name": "checkMnemonicDeriveSignKeys",
104 | "inputs": [
105 | {"name":"pub","type":"uint256"},
106 | {"name":"sec","type":"uint256"}
107 | ],
108 | "outputs": [
109 | ]
110 | },
111 | {
112 | "name": "testMnemonic",
113 | "inputs": [
114 | {"name":"index","type":"uint32"}
115 | ],
116 | "outputs": [
117 | ]
118 | },
119 | {
120 | "name": "genMnemonic",
121 | "inputs": [
122 | {"name":"phrase","type":"bytes"}
123 | ],
124 | "outputs": [
125 | ]
126 | },
127 | {
128 | "name": "verifyPhrase",
129 | "inputs": [
130 | {"name":"valid","type":"bool"}
131 | ],
132 | "outputs": [
133 | ]
134 | },
135 | {
136 | "name": "testString",
137 | "inputs": [
138 | {"name":"index","type":"uint32"}
139 | ],
140 | "outputs": [
141 | ]
142 | },
143 | {
144 | "name": "testCut1",
145 | "inputs": [
146 | {"name":"substr","type":"bytes"}
147 | ],
148 | "outputs": [
149 | ]
150 | },
151 | {
152 | "name": "testCut2",
153 | "inputs": [
154 | {"name":"substr","type":"bytes"}
155 | ],
156 | "outputs": [
157 | ]
158 | },
159 | {
160 | "name": "testAccount",
161 | "inputs": [
162 | ],
163 | "outputs": [
164 | ]
165 | },
166 | {
167 | "name": "setBalance",
168 | "inputs": [
169 | {"name":"nanotokens","type":"uint128"}
170 | ],
171 | "outputs": [
172 | ]
173 | },
174 | {
175 | "name": "setBalance2",
176 | "inputs": [
177 | {"name":"nanotokens","type":"uint128"}
178 | ],
179 | "outputs": [
180 | ]
181 | },
182 | {
183 | "name": "setAccountType",
184 | "inputs": [
185 | {"name":"acc_type","type":"int8"}
186 | ],
187 | "outputs": [
188 | ]
189 | },
190 | {
191 | "name": "setAccountType2",
192 | "inputs": [
193 | {"name":"acc_type","type":"int8"}
194 | ],
195 | "outputs": [
196 | ]
197 | },
198 | {
199 | "name": "setCodeHash",
200 | "inputs": [
201 | {"name":"code_hash","type":"uint256"}
202 | ],
203 | "outputs": [
204 | ]
205 | },
206 | {
207 | "name": "setCodeHash2",
208 | "inputs": [
209 | {"name":"code_hash","type":"uint256"}
210 | ],
211 | "outputs": [
212 | ]
213 | },
214 | {
215 | "name": "testRandom",
216 | "inputs": [
217 | ],
218 | "outputs": [
219 | ]
220 | },
221 | {
222 | "name": "setRandom1",
223 | "inputs": [
224 | {"name":"buffer","type":"bytes"}
225 | ],
226 | "outputs": [
227 | ]
228 | },
229 | {
230 | "name": "setRandom2",
231 | "inputs": [
232 | {"name":"buffer","type":"bytes"}
233 | ],
234 | "outputs": [
235 | ]
236 | },
237 | {
238 | "name": "testNaclbox",
239 | "inputs": [
240 | ],
241 | "outputs": [
242 | ]
243 | },
244 | {
245 | "name": "getEnc",
246 | "inputs": [
247 | {"name":"encrypted","type":"bytes"}
248 | ],
249 | "outputs": [
250 | ]
251 | },
252 | {
253 | "name": "getDec",
254 | "inputs": [
255 | {"name":"decrypted","type":"bytes"}
256 | ],
257 | "outputs": [
258 | ]
259 | },
260 | {
261 | "name": "testKeysFromSecret",
262 | "inputs": [
263 | ],
264 | "outputs": [
265 | ]
266 | },
267 | {
268 | "name": "getPair",
269 | "inputs": [
270 | {"name":"publicKey","type":"uint256"},
271 | {"name":"secretKey","type":"uint256"}
272 | ],
273 | "outputs": [
274 | ]
275 | },
276 | {
277 | "name": "testHexEncode",
278 | "inputs": [
279 | ],
280 | "outputs": [
281 | ]
282 | },
283 | {
284 | "name": "hexEnc",
285 | "inputs": [
286 | {"name":"hexstr","type":"bytes"}
287 | ],
288 | "outputs": [
289 | ]
290 | },
291 | {
292 | "name": "testHexDecode",
293 | "inputs": [
294 | ],
295 | "outputs": [
296 | ]
297 | },
298 | {
299 | "name": "hexDec",
300 | "inputs": [
301 | {"name":"data","type":"bytes"}
302 | ],
303 | "outputs": [
304 | ]
305 | },
306 | {
307 | "name": "testBase64Encode",
308 | "inputs": [
309 | ],
310 | "outputs": [
311 | ]
312 | },
313 | {
314 | "name": "base64Enc",
315 | "inputs": [
316 | {"name":"base64","type":"bytes"}
317 | ],
318 | "outputs": [
319 | ]
320 | },
321 | {
322 | "name": "testBase64Decode",
323 | "inputs": [
324 | ],
325 | "outputs": [
326 | ]
327 | },
328 | {
329 | "name": "base64Dec",
330 | "inputs": [
331 | {"name":"data","type":"bytes"}
332 | ],
333 | "outputs": [
334 | ]
335 | },
336 | {
337 | "name": "testSign",
338 | "inputs": [
339 | ],
340 | "outputs": [
341 | ]
342 | },
343 | {
344 | "name": "setSigningBox",
345 | "inputs": [
346 | {"name":"handle","type":"uint32"}
347 | ],
348 | "outputs": [
349 | ]
350 | },
351 | {
352 | "name": "setSignature",
353 | "inputs": [
354 | {"name":"signature","type":"bytes"}
355 | ],
356 | "outputs": [
357 | ]
358 | },
359 | {
360 | "name": "getDebotOptions",
361 | "inputs": [
362 | ],
363 | "outputs": [
364 | {"name":"options","type":"uint8"},
365 | {"name":"debotAbi","type":"bytes"},
366 | {"name":"targetAbi","type":"bytes"},
367 | {"name":"targetAddr","type":"address"}
368 | ]
369 | },
370 | {
371 | "name": "setABI",
372 | "inputs": [
373 | {"name":"dabi","type":"bytes"}
374 | ],
375 | "outputs": [
376 | ]
377 | },
378 | {
379 | "name": "constructor",
380 | "inputs": [
381 | ],
382 | "outputs": [
383 | ]
384 | }
385 | ],
386 | "data": [
387 | ],
388 | "events": [
389 | ]
390 | }
391 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot3.sol:
--------------------------------------------------------------------------------
1 | pragma ton-solidity >=0.40.0;
2 | pragma AbiHeader expire;
3 | pragma AbiHeader time;
4 | pragma AbiHeader pubkey;
5 | import "../Debot.sol";
6 | import "../Sdk.sol";
7 | import "../Base64.sol";
8 | import "../Hex.sol";
9 | import "../Terminal.sol";
10 | import "../SigningBoxInput.sol";
11 |
12 | contract testDebot3 is Debot {
13 |
14 | /*
15 | Storage
16 | */
17 |
18 | uint32 m_rnd1;
19 | uint32 m_rnd2;
20 |
21 | /*
22 | * Overrided Debot functions
23 | */
24 |
25 | // Entry point for new debots
26 | function start() override public {
27 | runAll();
28 | }
29 |
30 | /// @notice Returns Metadata about DeBot.
31 | function getDebotInfo() public functionID(0xDEB) override view returns(
32 | string name, string version, string publisher, string caption, string author,
33 | address support, string hello, string language, string dabi, bytes icon
34 | ) {
35 | name = "TestSdk";
36 | version = "0.4.0";
37 | publisher = "TON Labs";
38 | caption = "Test for SDK interface";
39 | author = "TON Labs";
40 | support = address(0);
41 | hello = "Hello, I'm a test.";
42 | language = "en";
43 | dabi = m_debotAbi.get();
44 | icon = "";
45 | }
46 |
47 | function getRequiredInterfaces() public view override returns (uint256[] interfaces) {
48 | return [ Terminal.ID ];
49 | }
50 |
51 | function runAll() public {
52 | testMnemonic(0);
53 | testString(0);
54 | testMnemonicDeriveSignKeys(0);
55 | testhdkeyXprv(0);
56 | testAccount();
57 | testRandom();
58 | testNaclbox();
59 | testKeysFromSecret();
60 | testHexEncode();
61 | testBase64Encode();
62 | testSign();
63 | }
64 |
65 | function testhdkeyXprv(uint32 index) public {
66 | index = index;
67 | string ph = "blood genius security pen scissors tissue coil wish devote silk minimum remind";
68 | Sdk.hdkeyXprvFromMnemonic(tvm.functionId(hdkeyXprvFromMnemonicRes),ph);
69 | }
70 |
71 | function hdkeyXprvFromMnemonicRes(string xprv) public{
72 | require(xprv=="xprv9s21ZrQH143K4bDg2b9x7Y81Qw5LcfJ6D6YStM2rZVZP1DcYvmadfUXmV8wFb77Jp6s88VykAvdFAey3b5B1ykToXVJo5nnG26VVupdDxS3",130);
73 | Sdk.hdkeyDeriveFromXprv(tvm.functionId(hdkeyDeriveFromXprvRes),xprv,1,true);
74 | }
75 |
76 | function hdkeyDeriveFromXprvRes(string xprv) public{
77 | require(xprv=="xprv9vDCWeesvU6UAq8cHqF3Pxyrju8oWRw9czjRrGbHpRWhUrp36MxX2WbGKuQdtKB24Z7bsThjfexsnWFwpjU81WKhGE9KuT7RJmJ2yDb6TeJ",131);
78 | string path = "m/44'/396'/0'/0/1";
79 | Sdk.hdkeyDeriveFromXprvPath(tvm.functionId(hdkeyDeriveFromXprvPathRes),xprv,path);
80 | }
81 |
82 | function hdkeyDeriveFromXprvPathRes(string xprv) public{
83 | require(xprv=="xprvA5Hr4SR7z6JmHGYJmDJefc8PETc7JSEV7iQGmr1AxycsddzVvHeZPpomy4ygLDiUbUu7322yTba9JxomxPM3TNH4TVHx6ZDysE6WX3X5Ym9",132);
84 | Sdk.hdkeySecretFromXprv(tvm.functionId(hdkeySecretFromXprvRes),xprv);
85 | }
86 |
87 | function hdkeySecretFromXprvRes(uint256 sec) public{
88 | require(sec==0xa2087ef167360868a5153cd84182221388a79a26fe5a8557da0430b354dcc096,133);
89 | Sdk.naclSignKeypairFromSecretKey(tvm.functionId(naclSignKeypairFromSecretKeyRes),sec);
90 |
91 | }
92 | function naclSignKeypairFromSecretKeyRes(uint256 sec, uint256 pub) public{
93 | require(pub==0x33d6e80fb461e6b1f7592970112a13f398428dcecc18431fead5ade906bce304,134);
94 | require(sec==0xa2087ef167360868a5153cd84182221388a79a26fe5a8557da0430b354dcc096,135);
95 | Terminal.print(0, "test hdkeyXprv passed");
96 | }
97 |
98 | function testMnemonicDeriveSignKeys(uint32 index) public {
99 | index = index;
100 | string ph = "blood genius security pen scissors tissue coil wish devote silk minimum remind";
101 | string path = "m/44'/396'/0'/0/1";
102 | Sdk.mnemonicDeriveSignKeys(tvm.functionId(checkMnemonicDeriveSignKeys),ph,path);
103 | }
104 |
105 | function checkMnemonicDeriveSignKeys(uint256 pub, uint256 sec) public {
106 | require(pub == 0x07c31538a8371ced8ec6bd37c1b6dde86cf7246495e5ce538d58256c4f73dc5f,128);
107 | require(sec == 0xbc6464a6003bcb94659a03a1e705dd3d857bd270fb35acfd9bd460136e33ae39,129);
108 | Terminal.print(0, "test mnemonicDeriveSignKeys passed");
109 | }
110 |
111 |
112 | function testMnemonic(uint32 index) public {
113 | index = index;
114 | Sdk.mnemonicFromRandom(tvm.functionId(genMnemonic),1,12);
115 | }
116 |
117 | function genMnemonic(string phrase) public {
118 | Sdk.mnemonicVerify(tvm.functionId(verifyPhrase),phrase);
119 | }
120 |
121 | function verifyPhrase(bool valid) public {
122 | require(valid, 125);
123 | Terminal.print(0, "test mnemonic passed");
124 | }
125 |
126 | function testString(uint32 index) public {
127 | index = index;
128 | Sdk.substring(tvm.functionId(testCut1),"one two three",0,3);
129 | Sdk.substring(tvm.functionId(testCut2),"one two three",4,3);
130 | }
131 |
132 | function testCut1(string substr) public {
133 | require(substr=="one", 126);
134 | Terminal.print(0, "test substring1 passed");
135 | }
136 |
137 | function testCut2(string substr) public {
138 | require(substr=="two", 127);
139 | Terminal.print(0, "test substring2 passed");
140 | }
141 |
142 | function testAccount() public {
143 | Sdk.getBalance(tvm.functionId(setBalance), address(this));
144 | Sdk.getBalance(tvm.functionId(setBalance2), address.makeAddrStd(0, 1));
145 | }
146 |
147 | function setBalance(uint128 nanotokens) public {
148 | require(nanotokens > 0, 130);
149 | Sdk.getAccountType(tvm.functionId(setAccountType), address(this));
150 | Sdk.getAccountType(tvm.functionId(setAccountType2), address.makeAddrStd(0, 1));
151 | }
152 |
153 | function setBalance2(uint128 nanotokens) public pure {
154 | require(nanotokens == 0, 131);
155 | }
156 |
157 | function setAccountType(int8 acc_type) public {
158 | require(acc_type == 1, 132);
159 | Sdk.getAccountCodeHash(tvm.functionId(setCodeHash), address(this));
160 | Sdk.getAccountCodeHash(tvm.functionId(setCodeHash2), address.makeAddrStd(0, 1));
161 | }
162 |
163 | function setAccountType2(int8 acc_type) public pure {
164 | require(acc_type == -1, 133);
165 | }
166 |
167 | function setCodeHash(uint256 code_hash) public {
168 | require(code_hash != 0, 134);
169 | Terminal.print(0, "test account passed");
170 | }
171 |
172 | function setCodeHash2(uint256 code_hash) public pure {
173 | require(code_hash == 0, 135);
174 | }
175 |
176 | function testRandom() public {
177 | Sdk.genRandom(tvm.functionId(setRandom1), 32);
178 | Sdk.genRandom(tvm.functionId(setRandom2), 32);
179 | }
180 |
181 | function setRandom1(bytes buffer) public {
182 | m_rnd1 = buffer.toSlice().decode(uint32);
183 | }
184 |
185 | function setRandom2(bytes buffer) public {
186 | m_rnd2 = buffer.toSlice().decode(uint32);
187 | require(m_rnd1 != m_rnd2, 140);
188 | Terminal.print(0, "test genRandom passed");
189 | }
190 |
191 | function testNaclbox() public {
192 | /*
193 | const pub1 = "47F7C36DC0896FD2C020BB21F1605A3C161BF4EC5C5A23E5B5A111288CE59F19";
194 | const sec1 = "4DD67EBD0431CEC53C60499775423695C4407A2CFABB6E7569046C1E7445A89C";
195 |
196 | const pub2 = "552bc62d6e65294c0dea6c9143163dfcca6e1da4ea8411241e949925d07a0204";
197 | const sec2 = "6817601a9b60fc4c449d3dc72e30600bddc74eeb4ad00e8d4d223f4b6dd94f3c";
198 | */
199 | string dec = "hello";
200 | bytes nonce = bytes("000000000000000000000001");
201 | uint256 tp = 0x552bc62d6e65294c0dea6c9143163dfcca6e1da4ea8411241e949925d07a0204;
202 | uint256 s = 0x4DD67EBD0431CEC53C60499775423695C4407A2CFABB6E7569046C1E7445A89C;
203 | Sdk.naclBox(tvm.functionId(getEnc),dec,nonce,tp,s);
204 | }
205 |
206 | function getEnc(bytes encrypted)public {
207 | require(encrypted.length==21,151);
208 | Terminal.print(0,"test naclbox passed");
209 | bytes nonce = bytes("000000000000000000000001");
210 | uint256 tp = 0x47F7C36DC0896FD2C020BB21F1605A3C161BF4EC5C5A23E5B5A111288CE59F19;
211 | uint256 s = 0x6817601a9b60fc4c449d3dc72e30600bddc74eeb4ad00e8d4d223f4b6dd94f3c;
212 | Sdk.naclBoxOpen(tvm.functionId(getDec),encrypted,nonce,tp,s);
213 | }
214 |
215 | function getDec(bytes decrypted)public {
216 | require(string(decrypted)=="hello",152);
217 | Terminal.print(0,"test naclboxopen passed");
218 | }
219 |
220 | function testKeysFromSecret() public {
221 | uint256 sec = 0x4dd67ebd0431cec53c60499775423695c4407a2cfabb6e7569046c1e7445a89c;
222 | Sdk.naclKeypairFromSecret(tvm.functionId(getPair),sec);
223 | }
224 |
225 | function getPair(uint256 publicKey, uint256 secretKey)public {
226 | require(publicKey==0x47f7c36dc0896fd2c020bb21f1605a3c161bf4ec5c5a23e5b5a111288ce59f19,153);
227 | require(secretKey==0x4dd67ebd0431cec53c60499775423695c4407a2cfabb6e7569046c1e7445a89c,154);
228 | Terminal.print(0,"test naclKeypairFromSecret passed");
229 | }
230 |
231 | function testHexEncode() public {
232 | bytes data = bytes("hello");
233 | Hex.encode(tvm.functionId(hexEnc),data);
234 | }
235 | function hexEnc(string hexstr) public {
236 | require(hexstr=="68656c6c6f",130);
237 | Terminal.print(tvm.functionId(testHexDecode),"test hex encode passed");
238 | }
239 | function testHexDecode() public {
240 | string hexstr = "68656c6c6f";
241 | Hex.decode(tvm.functionId(hexDec),hexstr);
242 | }
243 | function hexDec(bytes data) public {
244 | require(string(data)=="hello",131);
245 | Terminal.print(0,"test hex decode passed");
246 | }
247 |
248 | function testBase64Encode() public {
249 | bytes data = bytes("hello");
250 | Base64.encode(tvm.functionId(base64Enc),data);
251 | }
252 | function base64Enc(string base64) public {
253 | require(base64=="aGVsbG8=",132);
254 | Terminal.print(tvm.functionId(testBase64Decode),"test base64 encode passed");
255 | }
256 | function testBase64Decode() public {
257 | string base64 = "aGVsbG8=";
258 | Base64.decode(tvm.functionId(base64Dec),base64);
259 | }
260 | function base64Dec(bytes data) public {
261 | require(string(data)=="hello",133);
262 | Terminal.print(0,"test base64 decode passed");
263 | }
264 |
265 | //
266 | // Sign functions
267 | //
268 |
269 | function testSign() public {
270 | uint256[] possibleKeys;
271 | SigningBoxInput.get(tvm.functionId(setSigningBox), "Enter key:", possibleKeys);
272 | }
273 |
274 | function setSigningBox(uint32 handle) public {
275 | uint256 hash = sha256("test sign string");
276 | Sdk.signHash(tvm.functionId(setSignature), handle, hash);
277 | }
278 |
279 | function setSignature(bytes signature) public {
280 | require(signature.length == 64, 200);
281 | Terminal.print(0,"test sign hash passed");
282 | uint256 hash = sha256("test sign string");
283 | require(tvm.checkSign(hash, signature.toSlice(), tvm.pubkey()), 201);
284 | }
285 | }
286 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot3.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot3.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot4.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"targetAbi","type":"bytes"},
9 | {"name":"targetAddr","type":"address"}
10 | ],
11 | "outputs": [
12 | ]
13 | },
14 | {
15 | "name": "setAbi",
16 | "inputs": [
17 | {"name":"debotAbi","type":"bytes"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "setImage",
24 | "inputs": [
25 | {"name":"image","type":"cell"},
26 | {"name":"pubkey","type":"uint256"}
27 | ],
28 | "outputs": [
29 | ]
30 | },
31 | {
32 | "name": "start",
33 | "inputs": [
34 | ],
35 | "outputs": [
36 | ]
37 | },
38 | {
39 | "name": "getVersion",
40 | "inputs": [
41 | ],
42 | "outputs": [
43 | {"name":"name","type":"bytes"},
44 | {"name":"semver","type":"uint24"}
45 | ]
46 | },
47 | {
48 | "name": "onSuccess",
49 | "inputs": [
50 | ],
51 | "outputs": [
52 | ]
53 | },
54 | {
55 | "name": "queryData",
56 | "inputs": [
57 | {"name":"value","type":"int256"}
58 | ],
59 | "outputs": [
60 | ]
61 | },
62 | {
63 | "name": "onDeployFailed",
64 | "inputs": [
65 | {"name":"sdkError","type":"uint32"},
66 | {"name":"exitCode","type":"uint32"}
67 | ],
68 | "outputs": [
69 | ]
70 | },
71 | {
72 | "name": "sendMsg",
73 | "inputs": [
74 | ],
75 | "outputs": [
76 | ]
77 | },
78 | {
79 | "name": "setData",
80 | "inputs": [
81 | {"name":"num","type":"uint256"}
82 | ],
83 | "outputs": [
84 | ]
85 | },
86 | {
87 | "name": "onError",
88 | "inputs": [
89 | {"name":"sdkError","type":"uint32"},
90 | {"name":"exitCode","type":"uint32"}
91 | ],
92 | "outputs": [
93 | ]
94 | },
95 | {
96 | "name": "setResult",
97 | "inputs": [
98 | ],
99 | "outputs": [
100 | ]
101 | },
102 | {
103 | "name": "setData2",
104 | "inputs": [
105 | {"name":"num","type":"uint256"}
106 | ],
107 | "outputs": [
108 | ]
109 | },
110 | {
111 | "name": "fetch",
112 | "inputs": [
113 | ],
114 | "outputs": [
115 | {"components":[{"name":"id","type":"uint8"},{"name":"desc","type":"bytes"},{"components":[{"name":"desc","type":"bytes"},{"name":"name","type":"bytes"},{"name":"actionType","type":"uint8"},{"name":"attrs","type":"bytes"},{"name":"to","type":"uint8"},{"name":"misc","type":"cell"}],"name":"actions","type":"tuple[]"}],"name":"contexts","type":"tuple[]"}
116 | ]
117 | },
118 | {
119 | "name": "getDebotOptions",
120 | "inputs": [
121 | ],
122 | "outputs": [
123 | {"name":"options","type":"uint8"},
124 | {"name":"debotAbi","type":"bytes"},
125 | {"name":"targetAbi","type":"bytes"},
126 | {"name":"targetAddr","type":"address"}
127 | ]
128 | }
129 | ],
130 | "data": [
131 | ],
132 | "events": [
133 | ]
134 | }
135 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot4.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot4.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot5.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | {"name":"codeHash","type":"uint256"}
9 | ],
10 | "outputs": [
11 | ]
12 | },
13 | {
14 | "name": "start",
15 | "inputs": [
16 | ],
17 | "outputs": [
18 | ]
19 | },
20 | {
21 | "name": "setHash",
22 | "inputs": [
23 | {"name":"value","type":"bytes"}
24 | ],
25 | "outputs": [
26 | ]
27 | },
28 | {
29 | "name": "getAccountsDataByHash",
30 | "inputs": [
31 | {"name":"value","type":"bool"}
32 | ],
33 | "outputs": [
34 | ]
35 | },
36 | {
37 | "name": "onDataResult",
38 | "inputs": [
39 | {"components":[{"name":"id","type":"address"},{"name":"data","type":"cell"}],"name":"accounts","type":"tuple[]"}
40 | ],
41 | "outputs": [
42 | ]
43 | },
44 | {
45 | "name": "getVersion",
46 | "inputs": [
47 | ],
48 | "outputs": [
49 | {"name":"name","type":"bytes"},
50 | {"name":"semver","type":"uint24"}
51 | ]
52 | },
53 | {
54 | "name": "getDebotOptions",
55 | "inputs": [
56 | ],
57 | "outputs": [
58 | {"name":"options","type":"uint8"},
59 | {"name":"debotAbi","type":"bytes"},
60 | {"name":"targetAbi","type":"bytes"},
61 | {"name":"targetAddr","type":"address"}
62 | ]
63 | },
64 | {
65 | "name": "setABI",
66 | "inputs": [
67 | {"name":"dabi","type":"bytes"}
68 | ],
69 | "outputs": [
70 | ]
71 | }
72 | ],
73 | "data": [
74 | ],
75 | "events": [
76 | ]
77 | }
78 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot5.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot5.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot6.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "start",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "onSuccess1",
14 | "inputs": [
15 | ],
16 | "outputs": [
17 | ]
18 | },
19 | {
20 | "name": "onSuccess2",
21 | "inputs": [
22 | ],
23 | "outputs": [
24 | ]
25 | },
26 | {
27 | "name": "onSuccess3",
28 | "inputs": [
29 | ],
30 | "outputs": [
31 | ]
32 | },
33 | {
34 | "name": "onError1",
35 | "inputs": [
36 | {"name":"sdkError","type":"uint32"},
37 | {"name":"exitCode","type":"uint32"}
38 | ],
39 | "outputs": [
40 | ]
41 | },
42 | {
43 | "name": "onError2",
44 | "inputs": [
45 | {"name":"sdkError","type":"uint32"},
46 | {"name":"exitCode","type":"uint32"}
47 | ],
48 | "outputs": [
49 | ]
50 | },
51 | {
52 | "name": "onError3",
53 | "inputs": [
54 | {"name":"sdkError","type":"uint32"},
55 | {"name":"exitCode","type":"uint32"}
56 | ],
57 | "outputs": [
58 | ]
59 | },
60 | {
61 | "name": "send3",
62 | "inputs": [
63 | ],
64 | "outputs": [
65 | ]
66 | },
67 | {
68 | "name": "send2",
69 | "inputs": [
70 | ],
71 | "outputs": [
72 | ]
73 | },
74 | {
75 | "name": "send1",
76 | "inputs": [
77 | {"name":"value1","type":"uint64"},
78 | {"name":"value2","type":"uint64"}
79 | ],
80 | "outputs": [
81 | ]
82 | },
83 | {
84 | "name": "getVersion",
85 | "inputs": [
86 | ],
87 | "outputs": [
88 | {"name":"name","type":"bytes"},
89 | {"name":"semver","type":"uint24"}
90 | ]
91 | },
92 | {
93 | "name": "getDebotOptions",
94 | "inputs": [
95 | ],
96 | "outputs": [
97 | {"name":"options","type":"uint8"},
98 | {"name":"debotAbi","type":"bytes"},
99 | {"name":"targetAbi","type":"bytes"},
100 | {"name":"targetAddr","type":"address"}
101 | ]
102 | },
103 | {
104 | "name": "setABI",
105 | "inputs": [
106 | {"name":"dabi","type":"bytes"}
107 | ],
108 | "outputs": [
109 | ]
110 | },
111 | {
112 | "name": "constructor",
113 | "inputs": [
114 | ],
115 | "outputs": [
116 | ]
117 | }
118 | ],
119 | "data": [
120 | ],
121 | "events": [
122 | ]
123 | }
124 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot6.sol:
--------------------------------------------------------------------------------
1 | pragma ton-solidity >=0.35.0;
2 | pragma AbiHeader expire;
3 | pragma AbiHeader time;
4 | pragma AbiHeader pubkey;
5 | // import required DeBot interfaces and basic DeBot contract.
6 | import "../Debot.sol";
7 | import "../Terminal.sol";
8 |
9 | contract testDebot is Debot {
10 |
11 | /// @notice Entry point function for DeBot.
12 | function start() public override {
13 | optional(uint256) pubkey = tvm.pubkey();
14 | this.send1{
15 | abiVer: 2,
16 | extMsg: true,
17 | sign: true,
18 | time: 0,
19 | expire: 0,
20 | pubkey: pubkey,
21 | callbackId: tvm.functionId(onSuccess1),
22 | onErrorId: tvm.functionId(onError1)
23 | }(2.2 ton, 3.5 ton);
24 |
25 | this.send2{
26 | abiVer: 2,
27 | extMsg: true,
28 | sign: true,
29 | time: 0,
30 | expire: 0,
31 | pubkey: pubkey,
32 | callbackId: tvm.functionId(onSuccess2),
33 | onErrorId: tvm.functionId(onError2)
34 | }();
35 |
36 | this.send3{
37 | abiVer: 2,
38 | extMsg: true,
39 | sign: true,
40 | time: 0,
41 | expire: 0,
42 | pubkey: pubkey,
43 | callbackId: tvm.functionId(onSuccess3),
44 | onErrorId: tvm.functionId(onError3)
45 | }();
46 | }
47 |
48 | function onSuccess1() public {
49 | Terminal.print(0, "Send1 succeeded");
50 | }
51 |
52 | function onSuccess2() public pure {
53 | require(false, 201);
54 | }
55 |
56 | function onSuccess3() public pure {
57 | require(false, 304);
58 | }
59 |
60 | function onError1(uint32 sdkError, uint32 exitCode) public pure {
61 | sdkError = sdkError;
62 | exitCode = exitCode;
63 | require(false, 200);
64 | }
65 |
66 | function onError2(uint32 sdkError, uint32 exitCode) public {
67 | require(sdkError == 812, 300);
68 | require(exitCode == 0, 301);
69 | Terminal.print(0, "Send2 rejected");
70 | }
71 |
72 | function onError3(uint32 sdkError, uint32 exitCode) public pure {
73 | require(sdkError == 414, 102);
74 | require(exitCode == 303, 103);
75 | }
76 |
77 | function send3() public view {
78 | require(false, 303);
79 | }
80 |
81 | function send2() public view {
82 | require(msg.pubkey() == tvm.pubkey(), 101);
83 | tvm.accept();
84 | address(this).transfer(10 ton, true, 1);
85 | }
86 |
87 | function send1(uint64 value1, uint64 value2) public view {
88 | require(msg.pubkey() == tvm.pubkey(), 101);
89 | tvm.accept();
90 | address(this).transfer(value1, true, 1);
91 | address addr = address.makeAddrStd(0, 0);
92 | addr.transfer(value2, false, 1);
93 | }
94 |
95 | // @notice Define DeBot version and title here.
96 | function getVersion() public override returns (string name, uint24 semver) {
97 | (name, semver) = ("Test DeBot 6 for testing approve callback", _version(0,1,0));
98 | }
99 |
100 | function _version(uint24 major, uint24 minor, uint24 fix) private pure inline returns (uint24) {
101 | return (major << 16) | (minor << 8) | (fix);
102 | }
103 |
104 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot6.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot6.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot7.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "start",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "setResult",
14 | "inputs": [
15 | {"name":"result","type":"bool"},
16 | {"components":[{"name":"name","type":"bytes"},{"name":"tags","type":"bytes[]"},{"name":"age","type":"uint8"},{"name":"numbers","type":"uint8[]"},{"name":"addrs","type":"map(address,bytes)"}],"name":"obj","type":"tuple"}
17 | ],
18 | "outputs": [
19 | ]
20 | },
21 | {
22 | "name": "getRequiredInterfaces",
23 | "inputs": [
24 | ],
25 | "outputs": [
26 | {"name":"interfaces","type":"uint256[]"}
27 | ]
28 | },
29 | {
30 | "name": "getDebotInfo",
31 | "id": "0xDEB",
32 | "inputs": [
33 | ],
34 | "outputs": [
35 | {"name":"name","type":"bytes"},
36 | {"name":"version","type":"bytes"},
37 | {"name":"publisher","type":"bytes"},
38 | {"name":"key","type":"bytes"},
39 | {"name":"author","type":"bytes"},
40 | {"name":"support","type":"address"},
41 | {"name":"hello","type":"bytes"},
42 | {"name":"language","type":"bytes"},
43 | {"name":"dabi","type":"bytes"},
44 | {"name":"icon","type":"bytes"}
45 | ]
46 | },
47 | {
48 | "name": "getVersion",
49 | "inputs": [
50 | ],
51 | "outputs": [
52 | {"name":"name","type":"bytes"},
53 | {"name":"semver","type":"uint24"}
54 | ]
55 | },
56 | {
57 | "name": "getDebotOptions",
58 | "inputs": [
59 | ],
60 | "outputs": [
61 | {"name":"options","type":"uint8"},
62 | {"name":"debotAbi","type":"bytes"},
63 | {"name":"targetAbi","type":"bytes"},
64 | {"name":"targetAddr","type":"address"}
65 | ]
66 | },
67 | {
68 | "name": "setABI",
69 | "inputs": [
70 | {"name":"dabi","type":"bytes"}
71 | ],
72 | "outputs": [
73 | ]
74 | },
75 | {
76 | "name": "constructor",
77 | "inputs": [
78 | ],
79 | "outputs": [
80 | ]
81 | }
82 | ],
83 | "data": [
84 | ],
85 | "events": [
86 | ]
87 | }
88 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot7.sol:
--------------------------------------------------------------------------------
1 | pragma ton-solidity >=0.40.0;
2 | pragma AbiHeader expire;
3 | pragma AbiHeader time;
4 | pragma AbiHeader pubkey;
5 | import "../Debot.sol";
6 | import "../Terminal.sol";
7 | import "../Json.sol";
8 |
9 | contract TestDebot7 is Debot {
10 | struct Info{
11 | string name;
12 | string[] tags;
13 | uint8 age;
14 | uint8[] numbers;
15 | mapping (address => string) addrs;
16 | }
17 |
18 | /// @notice Entry point function for DeBot.
19 | function start() public override {
20 | string json = "{\"name\":\"Joe\",\"tags\":[\"good\",\"bad\",\"ugly\"],\"age\":73,\"numbers\":[1,2,3],\"addrs\":{\"0:1111111111111111111111111111111111111111111111111111111111111111\":\"My main account\"}}";
21 | Json.deserialize(tvm.functionId(setResult), json);
22 | }
23 |
24 | function setResult(bool result, Info obj) public pure {
25 | uint8[] numbers = [1,2,3];
26 | string[] tags = ["good", "bad", "ugly"];
27 | require(result == true, 99);
28 | require(obj.name =="Joe", 100);
29 | for(uint i = 0; i < tags.length; i++) {
30 | require(tvm.hash(bytes(tags[i])) == tvm.hash(bytes(obj.tags[i])), (i << 4) & 1);
31 | }
32 | require(obj.age == 73, 102);
33 | for(uint i = 0; i < numbers.length; i++) {
34 | require(obj.numbers[i]==numbers[i], 103);
35 | }
36 | address testAddr = address.makeAddrStd(0, 0x1111111111111111111111111111111111111111111111111111111111111111);
37 | optional(string) titleOpt = obj.addrs.fetch(testAddr);
38 | require(titleOpt.hasValue(), 104);
39 | string title = titleOpt.get();
40 | require(tvm.hash(bytes(title)) == tvm.hash(bytes("My main account")), 105);
41 | }
42 |
43 | function getRequiredInterfaces() public view override returns (uint256[] interfaces) {
44 | return [ Terminal.ID, Json.ID ];
45 | }
46 |
47 | function getDebotInfo() public functionID(0xDEB) view override returns(
48 | string name, string version, string publisher, string key, string author,
49 | address support, string hello, string language, string dabi, bytes icon) {
50 | name = "Test DeBot 7";
51 | version = "0.1.0";
52 | publisher = "TON Labs";
53 | key = "Test for Json interface";
54 | author = "TON Labs";
55 | support = address(0);
56 | hello = "Test DeBot 7";
57 | language = "en";
58 | dabi = m_debotAbi.get();
59 | icon = "";
60 | }
61 |
62 | function getVersion() public override returns (string name, uint24 semver) {
63 | name = "Test DeBot 7";
64 | semver = 1 << 8;
65 | }
66 |
67 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot7.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot7.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot8.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["pubkey", "time", "expire"],
4 | "functions": [
5 | {
6 | "name": "start",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "setResponse",
14 | "inputs": [
15 | {"name":"statusCode","type":"int32"},
16 | {"name":"retHeaders","type":"bytes[]"},
17 | {"name":"content","type":"bytes"}
18 | ],
19 | "outputs": [
20 | ]
21 | },
22 | {
23 | "name": "setGetResponse",
24 | "inputs": [
25 | {"name":"statusCode","type":"int32"},
26 | {"name":"retHeaders","type":"bytes[]"},
27 | {"name":"content","type":"bytes"}
28 | ],
29 | "outputs": [
30 | ]
31 | },
32 | {
33 | "name": "setResult",
34 | "inputs": [
35 | {"name":"result","type":"bool"},
36 | {"components":[{"components":[{"name":"ProviderCode","type":"uint32"},{"name":"CountryIso","type":"bytes"},{"name":"Name","type":"bytes"},{"name":"LogoUrl","type":"bytes"}],"name":"Result","type":"tuple[]"},{"name":"Status","type":"bytes"}],"name":"obj","type":"tuple"}
37 | ],
38 | "outputs": [
39 | ]
40 | },
41 | {
42 | "name": "setResult2",
43 | "inputs": [
44 | {"name":"result","type":"bool"},
45 | {"components":[{"components":[{"name":"name1","type":"bytes"}],"name":"args","type":"tuple"},{"components":[{"name":"Accept","type":"bytes"},{"name":"Host","type":"bytes"},{"name":"X_Amzn_Trace_Id","type":"bytes"}],"name":"headers","type":"tuple"},{"name":"origin","type":"bytes"},{"name":"url","type":"bytes"}],"name":"obj","type":"tuple"}
46 | ],
47 | "outputs": [
48 | ]
49 | },
50 | {
51 | "name": "getRequiredInterfaces",
52 | "inputs": [
53 | ],
54 | "outputs": [
55 | {"name":"interfaces","type":"uint256[]"}
56 | ]
57 | },
58 | {
59 | "name": "getDebotInfo",
60 | "id": "0xDEB",
61 | "inputs": [
62 | ],
63 | "outputs": [
64 | {"name":"name","type":"bytes"},
65 | {"name":"version","type":"bytes"},
66 | {"name":"publisher","type":"bytes"},
67 | {"name":"key","type":"bytes"},
68 | {"name":"author","type":"bytes"},
69 | {"name":"support","type":"address"},
70 | {"name":"hello","type":"bytes"},
71 | {"name":"language","type":"bytes"},
72 | {"name":"dabi","type":"bytes"},
73 | {"name":"icon","type":"bytes"}
74 | ]
75 | },
76 | {
77 | "name": "getDebotOptions",
78 | "inputs": [
79 | ],
80 | "outputs": [
81 | {"name":"options","type":"uint8"},
82 | {"name":"debotAbi","type":"bytes"},
83 | {"name":"targetAbi","type":"bytes"},
84 | {"name":"targetAddr","type":"address"}
85 | ]
86 | },
87 | {
88 | "name": "setABI",
89 | "inputs": [
90 | {"name":"dabi","type":"bytes"}
91 | ],
92 | "outputs": [
93 | ]
94 | },
95 | {
96 | "name": "constructor",
97 | "inputs": [
98 | ],
99 | "outputs": [
100 | ]
101 | }
102 | ],
103 | "data": [
104 | ],
105 | "events": [
106 | ]
107 | }
108 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot8.sol:
--------------------------------------------------------------------------------
1 | pragma ton-solidity >=0.40.0;
2 | pragma AbiHeader expire;
3 | pragma AbiHeader time;
4 | pragma AbiHeader pubkey;
5 | import "../Debot.sol";
6 | import "../Terminal.sol";
7 | import "../Network.sol";
8 | import "../Json.sol";
9 |
10 | contract TestDebot8 is Debot {
11 |
12 | struct Response {
13 | Provider[] Result;
14 | string Status;
15 | }
16 |
17 | struct Provider {
18 | uint32 ProviderCode;
19 | string CountryIso;
20 | string Name;
21 | string LogoUrl;
22 | }
23 |
24 | struct Args {
25 | string name1;
26 | }
27 | struct Headers {
28 | string Accept;
29 | string Host;
30 | string X_Amzn_Trace_Id;
31 | }
32 | struct GetResponse {
33 | Args args;
34 | Headers headers;
35 | string origin;
36 | string url;
37 | }
38 |
39 | function start() public override {
40 | string[] headers;
41 | string url = "http://ptsv2.com/t/qajss-1618330246/post";
42 | headers.push("Content-Type: application/x-www-form-urlencoded");
43 | string body = "key1=value1";
44 | Network.post(tvm.functionId(setResponse), url, headers, body);
45 | url = "https://httpbin.org/get?name1=value1";
46 | string[] headers2;
47 | Network.get(tvm.functionId(setGetResponse), url, headers2);
48 | }
49 |
50 | function setResponse(int32 statusCode, string[] retHeaders, string content) public {
51 | retHeaders = retHeaders;
52 | require(statusCode == 200, 199);
53 | Json.deserialize(tvm.functionId(setResult), content);
54 | }
55 |
56 | function setGetResponse(int32 statusCode, string[] retHeaders, string content) public {
57 | retHeaders = retHeaders;
58 | require(statusCode == 200, 199);
59 | Json.deserialize(tvm.functionId(setResult2), content);
60 | }
61 |
62 | function setResult(bool result, Response obj) public pure {
63 | require(result == true, 200);
64 | require(tvm.hash(bytes(obj.Status)) == tvm.hash(bytes("success")), 201);
65 | require(obj.Result[0].ProviderCode == 678, 202);
66 | require(tvm.hash(bytes(obj.Result[0].Name)) == tvm.hash(bytes("Wonderland")), 203);
67 | require(tvm.hash(bytes(obj.Result[0].CountryIso)) == tvm.hash(bytes("WDL")), 204);
68 | require(tvm.hash(bytes(obj.Result[0].LogoUrl)) == tvm.hash(bytes("http://path.to.logo/url")), 205);
69 | }
70 |
71 | function setResult2(bool result, GetResponse obj) public pure {
72 | require(result == true, 300);
73 | require(tvm.hash(bytes(obj.args.name1)) == tvm.hash(bytes("value1")), 301);
74 | }
75 |
76 | function getRequiredInterfaces() public view override returns (uint256[] interfaces) {
77 | return [ Terminal.ID, Network.ID, Json.ID ];
78 | }
79 |
80 | function getDebotInfo() public functionID(0xDEB) view override returns(
81 | string name, string version, string publisher, string key, string author,
82 | address support, string hello, string language, string dabi, bytes icon) {
83 | name = "Test DeBot 8";
84 | version = "0.1.0";
85 | publisher = "TON Labs";
86 | string iface = "Network";
87 | key = format("Test for {} interface", iface);
88 | author = "TON Labs";
89 | support = address(0);
90 | hello = "Test DeBot 8";
91 | language = "en";
92 | dabi = m_debotAbi.get();
93 | icon = "";
94 | }
95 | }
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot8.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebot8.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebotTarget.abi.json:
--------------------------------------------------------------------------------
1 | {
2 | "ABI version": 2,
3 | "header": ["time", "expire"],
4 | "functions": [
5 | {
6 | "name": "constructor",
7 | "inputs": [
8 | ],
9 | "outputs": [
10 | ]
11 | },
12 | {
13 | "name": "getData",
14 | "inputs": [
15 | {"name":"key","type":"uint32"}
16 | ],
17 | "outputs": [
18 | {"name":"num","type":"uint256"}
19 | ]
20 | },
21 | {
22 | "name": "setData",
23 | "inputs": [
24 | {"name":"key","type":"uint32"},
25 | {"name":"val","type":"uint256"}
26 | ],
27 | "outputs": [
28 | ]
29 | }
30 | ],
31 | "data": [
32 | ],
33 | "events": [
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebotTarget.tvc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nerzh/everscale-client-swift/295076ad5e3acadb8de8b5b61819522df6912e33/Tests/EverscaleClientSwiftTests/Fixtures/abi/testDebotTarget.tvc
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/NetTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 21.10.2020.
6 | //
7 |
8 | import XCTest
9 | import class Foundation.Bundle
10 | @testable import EverscaleClientSwift
11 | @testable import CTonSDK
12 | @testable import SwiftExtensionsPack
13 |
14 | final class NetTests: XCTestCase {
15 |
16 | func testQuery_collection() throws {
17 | try testAsyncMethods { (client, group) in
18 | group.enter()
19 | let any = AnyValue.object(
20 | [
21 | "created_at" : AnyValue.object(
22 | [
23 | "gt" : AnyValue.int(1562342740)
24 | ])
25 | ])
26 | let payload: TSDKParamsOfQueryCollection = .init(collection: "messages",
27 | filter: any,
28 | result: "body created_at",
29 | order: nil,
30 | limit: nil)
31 | try client.net.query_collection(payload) { [group] (response) in
32 | if let first = response.result?.result.first?.toAny() as? [String: Any] {
33 | let created_at: Int? = first["created_at"] as? Int
34 | XCTAssertTrue(created_at ?? 0 > 1562342740)
35 | } else {
36 | XCTAssertTrue(false, "No Data")
37 | }
38 | group.leave()
39 | }
40 | group.wait()
41 | }
42 | }
43 |
44 | func testWait_for_collection() throws {
45 | try testAsyncMethods { (client, group) in
46 | let now: Int = Int(Date().timeIntervalSince1970)
47 | let any = AnyValue.object(
48 | [
49 | "now" : AnyValue.object(
50 | [
51 | "gt" : AnyValue.int(now)
52 | ])
53 | ])
54 | let payload: TSDKParamsOfWaitForCollection = .init(collection: "transactions",
55 | filter: any,
56 | result: "id now",
57 | timeout: nil)
58 | group.enter()
59 | try client.net.wait_for_collection(payload) { [group] (response) in
60 | if let json = response.result?.result.toAny() as? [String: Any],
61 | let thisNow = json["now"] as? Int
62 | {
63 | XCTAssertTrue(thisNow > now)
64 | } else {
65 | XCTAssertTrue(false, "No Data")
66 | }
67 | group.leave()
68 | }
69 | Thread {
70 | // Just generate transactions
71 | usleep(1_000_000)
72 | for _ in 1...2 {
73 | _ = try? self.getGramsFromGiverSync(client)
74 | }
75 | }.start()
76 | group.wait()
77 | }
78 | }
79 |
80 | func testSubscribe_collection() throws {
81 | try testAsyncMethods { (client, group) in
82 | group.enter()
83 | let payload: TSDKParamsOfSubscribeCollection = .init(collection: "transactions",
84 | filter: nil,
85 | result: "id account_addr")
86 | try client.net.subscribe_collection(payload) { [group] (response) in
87 | if response.result?.handle != nil {
88 | BindingStore.deleteResponseHandler(response.requestId)
89 | group.leave()
90 | return
91 | } else if let result = response.rawResponse.toModel(TSDKDefault.self)?.result?.toAny() as? [String: Any],
92 | let account_addr = result["account_addr"]
93 | {
94 | XCTAssertTrue((account_addr as? String) != nil)
95 | }
96 | if response.finished {
97 | BindingStore.deleteResponseHandler(response.requestId)
98 | group.leave()
99 | }
100 | }
101 | group.wait()
102 | }
103 | }
104 |
105 |
106 | func testUnsubscribe() throws {
107 | try testAsyncMethods { (client, group) in
108 | /// groupCounter - for safe exit from response if execute "UNSUBSCRIBE THREAD"
109 | var groupCounter: Int = .init()
110 | let groupCounterLock: NSLock = .init()
111 |
112 | group.enter()
113 | groupCounter += 1
114 | let payload: TSDKParamsOfSubscribeCollection = .init(collection: "transactions",
115 | filter: nil,
116 | result: "id account_addr")
117 | var handle: UInt32 = .init()
118 | var requestId: UInt32 = .init()
119 | let handleGroup: DispatchGroup = .init()
120 | handleGroup.enter()
121 | try client.net.subscribe_collection(payload) { [group, handleGroup, groupCounterLock] (response) in
122 | groupCounterLock.lock()
123 | if response.result != nil {
124 | XCTAssertTrue(response.result?.handle != nil)
125 | handle = response.result?.handle ?? 0
126 | requestId = response.requestId
127 | handleGroup.leave()
128 | }
129 | if response.finished {
130 | BindingStore.deleteResponseHandler(response.requestId)
131 | if groupCounter > 0 {
132 | groupCounter -= 1
133 | group.leave()
134 | }
135 | }
136 | groupCounterLock.unlock()
137 | }
138 |
139 | groupCounterLock.lock()
140 | let copyRequestId: UInt32 = requestId
141 | groupCounterLock.unlock()
142 | Thread { [group, copyRequestId, groupCounterLock] in
143 | sleep(5)
144 | groupCounterLock.lock()
145 | if groupCounter > 0 {
146 | groupCounter -= 1
147 | BindingStore.deleteResponseHandler(copyRequestId)
148 | XCTAssertTrue(false, "NOT UNSUBSCRIBED")
149 | group.leave()
150 | }
151 | groupCounterLock.unlock()
152 | }.start()
153 | handleGroup.wait()
154 |
155 | group.enter()
156 | groupCounter += 1
157 | let payloadUnsubscribe: TSDKResultOfSubscribeCollection = .init(handle: handle)
158 | try client.net.unsubscribe(payloadUnsubscribe) { [group, groupCounterLock] (response) in
159 | groupCounterLock.lock()
160 | if groupCounter > 0 {
161 | groupCounter -= 1
162 | group.leave()
163 | }
164 | groupCounterLock.unlock()
165 | }
166 | group.wait()
167 | }
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/ProcessingTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 27.10.2020.
6 | //
7 |
8 | import XCTest
9 | import class Foundation.Bundle
10 | @testable import EverscaleClientSwift
11 | @testable import CTonSDK
12 | @testable import SwiftExtensionsPack
13 |
14 | final class ProcessingTests: XCTestCase {
15 |
16 | func testWait_for_transaction() throws {
17 | try testAsyncMethods { (client, group) in
18 | let tvcData: Data = self.readTvc("Events")
19 | let abiJSONValue: AnyValue = self.readAbi("Events")
20 | let abi: TSDKAbi = .init(type: .Serialized, value: abiJSONValue)
21 | let keys: TSDKKeyPair = try self.generateKeys()
22 | let signer: TSDKSigner = .init(type: .Keys,
23 | public_key: nil,
24 | keys: keys,
25 | handle: nil)
26 | let callSet: TSDKCallSet = .init(function_name: "constructor",
27 | header: TSDKFunctionHeader(expire: nil,
28 | time: nil,
29 | pubkey: keys.public),
30 | input: nil)
31 | let deploySet: TSDKDeploySet = .init(tvc: tvcData.base64EncodedString(), workchain_id: nil, initial_data: nil)
32 | let payloadEncodeMessage: TSDKParamsOfEncodeMessage = .init(abi: abi,
33 | address: nil,
34 | deploy_set: deploySet,
35 | call_set: callSet,
36 | signer: signer,
37 | processing_try_index: nil)
38 | var encodedMessage: TSDKResultOfEncodeMessage!
39 | group.enter()
40 | try client.abi.encode_message(payloadEncodeMessage) { [group] (response) in
41 | guard let responseResult = response.result else {
42 | XCTAssertTrue(response.result?.address != nil, "Must be not nil")
43 | return
44 | }
45 | encodedMessage = responseResult
46 | group.leave()
47 | }
48 | group.wait()
49 | Log.warn("address - ", encodedMessage.address)
50 |
51 | try self.getGramsFromGiverSync(client, encodedMessage.address)
52 |
53 | let paramsOfSendMessage: TSDKParamsOfSendMessage = .init(message: encodedMessage.message, abi: abi, send_events: true)
54 | var maybeResultOfSendMessage: TSDKResultOfSendMessage?
55 | group.enter()
56 | try client.processing.send_message(paramsOfSendMessage) { (response) in
57 | if response.result != nil {
58 | maybeResultOfSendMessage = response.result
59 | }
60 | if response.finished {
61 | group.leave()
62 | }
63 | }
64 | group.wait()
65 | guard let resultOfSendMessage = maybeResultOfSendMessage else {
66 | XCTAssertTrue(false, "resultOfSendMessage is nil")
67 | return
68 | }
69 |
70 | let paramsOfWaitForTransaction: TSDKParamsOfWaitForTransaction = .init(abi: abi,
71 | message: encodedMessage.message,
72 | shard_block_id: resultOfSendMessage.shard_block_id,
73 | send_events: true)
74 | var resultOfProcessMessage: TSDKResultOfProcessMessage?
75 | group.enter()
76 | try client.processing.wait_for_transaction(paramsOfWaitForTransaction) { (response) in
77 | if response.result != nil {
78 | resultOfProcessMessage = response.result
79 | }
80 | if response.finished {
81 | group.leave()
82 | }
83 | }
84 | group.wait()
85 | XCTAssertEqual(resultOfProcessMessage?.out_messages.count, 0)
86 | XCTAssertEqual(resultOfProcessMessage?.decoded?.out_messages.count, 0)
87 | XCTAssertNil(resultOfProcessMessage?.decoded?.output)
88 | }
89 | }
90 |
91 | func testProcess_mesage() throws {
92 | try testAsyncMethods { (client, group) in
93 | let tvcData: Data = self.generateAbiAndTvc("Events").tvc
94 | let abiJSONValue: AnyValue = self.generateAbiAndTvc("Events").abiJSON
95 | let abi: TSDKAbi = .init(type: .Serialized, value: abiJSONValue)
96 | let keys: TSDKKeyPair = try self.generateKeys()
97 | let signer: TSDKSigner = .init(type: .Keys,
98 | public_key: nil,
99 | keys: keys,
100 | handle: nil)
101 | let callSet: TSDKCallSet = .init(function_name: "constructor",
102 | header: TSDKFunctionHeader(expire: nil,
103 | time: nil,
104 | pubkey: keys.public),
105 | input: nil)
106 | let deploySet: TSDKDeploySet = .init(tvc: tvcData.base64EncodedString(), workchain_id: nil, initial_data: nil)
107 | let payloadEncodeMessage: TSDKParamsOfEncodeMessage = .init(abi: abi,
108 | address: nil,
109 | deploy_set: deploySet,
110 | call_set: callSet,
111 | signer: signer,
112 | processing_try_index: nil)
113 | var result: TSDKResultOfEncodeMessage!
114 | group.enter()
115 | try client.abi.encode_message(payloadEncodeMessage) { [group] (response) in
116 | guard let responseResult = response.result else {
117 | XCTAssertTrue(response.result?.address != nil, "Must be not nil")
118 | return
119 | }
120 | result = responseResult
121 | group.leave()
122 | }
123 | group.wait()
124 | Log.warn("address - ", result.address)
125 | try self.getGramsFromGiverSync(client, result.address)
126 |
127 | let payloadProcessMessage: TSDKParamsOfProcessMessage = .init(message_encode_params: payloadEncodeMessage, send_events: true)
128 | var resultOfProcessMessage: TSDKResultOfProcessMessage?
129 | group.enter()
130 | try client.processing.process_message(payloadProcessMessage) { [group] (response) in
131 | if let result = response.result {
132 | resultOfProcessMessage = result
133 | }
134 | if response.finished {
135 | group.leave()
136 | }
137 | }
138 | group.wait()
139 |
140 | if let resultOfProcessMessage = resultOfProcessMessage {
141 | XCTAssertTrue(resultOfProcessMessage.fees.total_account_fees > 0)
142 | XCTAssertEqual(resultOfProcessMessage.out_messages.count, 0)
143 | XCTAssertEqual(resultOfProcessMessage.decoded?.out_messages.count, 0)
144 | XCTAssertNil(resultOfProcessMessage.decoded?.output)
145 | } else {
146 | XCTAssertTrue(false, "resultOfProcessMessage is nil")
147 | }
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/Tests/EverscaleClientSwiftTests/UtilsTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // File.swift
3 | //
4 | //
5 | // Created by Oleh Hudeichuk on 18.11.2020.
6 | //
7 |
8 | import XCTest
9 | import class Foundation.Bundle
10 | @testable import EverscaleClientSwift
11 |
12 | final class UtilsTests: XCTestCase {
13 |
14 | func testAccountIdToHex() throws {
15 | try testAsyncMethods { [self] (client, group) in
16 | group.enter()
17 | let format: TSDKAddressStringFormat = .init(type: .Hex, url: nil, test: nil, bounce: nil)
18 | let payload: TSDKParamsOfConvertAddress = .init(address: self.accountId, output_format: format)
19 | var maybeResultOfConvertAddress: TSDKResultOfConvertAddress?
20 | try client.utils.convert_address(payload) { (response) in
21 | if let result = response.result {
22 | maybeResultOfConvertAddress = result
23 | }
24 | if response.finished {
25 | group.leave()
26 | }
27 | }
28 | group.wait()
29 | guard let resultOfConvertAddress = maybeResultOfConvertAddress else {
30 | XCTAssertTrue(false, "resultOfConvertAddress must not be nil")
31 | return
32 | }
33 | XCTAssertEqual(resultOfConvertAddress.address, self.hexWorkchain0)
34 | }
35 | }
36 |
37 | func testAccountIdToAccountId() throws {
38 | try testAsyncMethods { [self] (client, group) in
39 | group.enter()
40 | let format: TSDKAddressStringFormat = .init(type: .AccountId, url: nil, test: nil, bounce: nil)
41 | let payload: TSDKParamsOfConvertAddress = .init(address: self.accountId, output_format: format)
42 | var maybeResultOfConvertAddress: TSDKResultOfConvertAddress?
43 | try client.utils.convert_address(payload) { (response) in
44 | if let result = response.result {
45 | maybeResultOfConvertAddress = result
46 | }
47 | if response.finished {
48 | group.leave()
49 | }
50 | }
51 | group.wait()
52 | guard let resultOfConvertAddress = maybeResultOfConvertAddress else {
53 | XCTAssertTrue(false, "resultOfConvertAddress must not be nil")
54 | return
55 | }
56 | XCTAssertEqual(resultOfConvertAddress.address, self.accountId)
57 | }
58 | }
59 |
60 | func testHexToBase64() throws {
61 | try testAsyncMethods { [self] (client, group) in
62 | group.enter()
63 | let format: TSDKAddressStringFormat = .init(type: .Base64, url: false, test: false, bounce: false)
64 | let payload: TSDKParamsOfConvertAddress = .init(address: self.hex, output_format: format)
65 | var maybeResultOfConvertAddress: TSDKResultOfConvertAddress?
66 | try client.utils.convert_address(payload) { (response) in
67 | if let result = response.result {
68 | maybeResultOfConvertAddress = result
69 | }
70 | if response.finished {
71 | group.leave()
72 | }
73 | }
74 | group.wait()
75 | guard let resultOfConvertAddress = maybeResultOfConvertAddress else {
76 | XCTAssertTrue(false, "resultOfConvertAddress must not be nil")
77 | return
78 | }
79 | XCTAssertEqual(resultOfConvertAddress.address, self.base64)
80 | }
81 | }
82 |
83 | func testBase64ToBase64URL() throws {
84 | try testAsyncMethods { [self] (client, group) in
85 | group.enter()
86 | let format: TSDKAddressStringFormat = .init(type: .Base64, url: true, test: true, bounce: true)
87 | let payload: TSDKParamsOfConvertAddress = .init(address: self.base64, output_format: format)
88 | var maybeResultOfConvertAddress: TSDKResultOfConvertAddress?
89 | try client.utils.convert_address(payload) { (response) in
90 | if let result = response.result {
91 | maybeResultOfConvertAddress = result
92 | }
93 | if response.finished {
94 | group.leave()
95 | }
96 | }
97 | group.wait()
98 | guard let resultOfConvertAddress = maybeResultOfConvertAddress else {
99 | XCTAssertTrue(false, "resultOfConvertAddress must not be nil")
100 | return
101 | }
102 | XCTAssertEqual(resultOfConvertAddress.address, self.base64url)
103 | }
104 | }
105 |
106 | func testBase64URLToHex() throws {
107 | try testAsyncMethods { [self] (client, group) in
108 | group.enter()
109 | let format: TSDKAddressStringFormat = .init(type: .Hex, url: nil, test: nil, bounce: nil)
110 | let payload: TSDKParamsOfConvertAddress = .init(address: self.base64url, output_format: format)
111 | var maybeResultOfConvertAddress: TSDKResultOfConvertAddress?
112 | try client.utils.convert_address(payload) { (response) in
113 | if let result = response.result {
114 | maybeResultOfConvertAddress = result
115 | }
116 | if response.finished {
117 | group.leave()
118 | }
119 | }
120 | group.wait()
121 | guard let resultOfConvertAddress = maybeResultOfConvertAddress else {
122 | XCTAssertTrue(false, "resultOfConvertAddress must not be nil")
123 | return
124 | }
125 | XCTAssertEqual(resultOfConvertAddress.address, self.hex)
126 | }
127 | }
128 |
129 |
130 | let accountId: String = "fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260"
131 | let hex: String = "-1:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260"
132 | let hexWorkchain0: String = "0:fcb91a3a3816d0f7b8c2c76108b8a9bc5a6b7a55bd79f8ab101c52db29232260"
133 | let base64: String = "Uf/8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15+KsQHFLbKSMiYG+9"
134 | let base64url: String = "kf_8uRo6OBbQ97jCx2EIuKm8Wmt6Vb15-KsQHFLbKSMiYIny"
135 | }
136 |
137 |
--------------------------------------------------------------------------------
/Tests/LinuxMain.swift:
--------------------------------------------------------------------------------
1 | import XCTest
2 |
3 | import EverscaleClientSwiftTests
4 |
5 | var tests = [XCTestCaseEntry]()
6 |
7 | XCTMain(tests)
8 |
--------------------------------------------------------------------------------
/api_generate.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | git pull --ff-only
4 | cd ApiParser
5 | swift build -c release
6 | curl https://raw.githubusercontent.com/everx-labs/ever-sdk/refs/heads/master/tools/api.json > api.json
7 | if [ `uname -m` = arm64 ]; then
8 | ./.build/arm64-apple-macosx/release/ApiParser ./api.json
9 | else
10 | ./.build/x86_64-apple-macosx/release/ApiParser ./api.json
11 | fi
12 |
--------------------------------------------------------------------------------
/scripts/install_rust.sh:
--------------------------------------------------------------------------------
1 | commandExist() {
2 | which $1 > /dev/null && echo '1' && return;
3 | echo '0';
4 | }
5 |
6 | if [ $(commandExist 'cargo') == "1" ]; then
7 | echo "RUST ALREADY INSTALLED TO YOUR OS";
8 | else
9 | echo "CARGO NOT FOUND";
10 | echo "INSTALL RUST TO YOUR OS ?";
11 | echo "y / n ?";
12 | read answer
13 | if [ $answer == "y" ]; then
14 | if [ $(commandExist 'curl') != "1" ]; then
15 | echo "Please install curl";
16 | exit 0;
17 | fi
18 | echo "INSTALL RUST...";
19 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
20 | source ~/.profile
21 | else
22 | echo "RUST NOT INSTALLED. EXIT.";
23 | exit 0;
24 | fi
25 | fi;
26 |
27 | if [ `uname -s` = Darwin ]; then
28 | source ~/.profile
29 | echo "Install cargo-lipo"
30 | USER=$(whoami)
31 | sudo -H -u $USER bash -lc 'cargo install cargo-lipo'
32 | sudo -H -u $USER bash -lc 'rustup target add aarch64-apple-ios x86_64-apple-ios'
33 | fi
34 |
35 | echo $'\nINSTALLATION RUST COMPLETE'
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/scripts/install_tonsdk.sh:
--------------------------------------------------------------------------------
1 | commandExist() {
2 | which $1 > /dev/null && echo '1' && return;
3 | echo '0';
4 | }
5 |
6 | if [ `uname -s` = Linux ]; then
7 | sudo echo $(whoami)
8 | fi
9 |
10 |
11 | # INSTALL RUST
12 | SCRIPTPATH="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
13 | bash "$SCRIPTPATH/install_rust.sh"
14 | source ~/.profile
15 |
16 | # INSTALL SDK
17 | if [ -d "./SDK" ]; then
18 | echo "SDK FOLDER ALREADY EXISTS"
19 | else
20 | git clone https://github.com/tonlabs/ever-sdk.git ./SDK
21 | fi
22 | cd ./SDK && git reset --hard HEAD && git pull --ff-only
23 | cargo update
24 |
25 | # if [ `uname -s` = Darwin ]; then
26 | # if [ `uname -m` = arm64 ]; then
27 | # rustup target add x86_64-apple-darwin
28 | # cargo build --release --target x86_64-apple-darwin
29 | # else
30 | # cargo build --release
31 | # fi
32 | # else
33 | # cargo build --release
34 | # fi
35 | cargo build --release
36 |
37 | if [ `uname -s` = Darwin ]; then
38 | if [ $(commandExist 'port') == "1" ]; then
39 | MACOS_LIB_INCLUDE_DIR="/opt/local"
40 | echo "CHOOSE MACOS MACPORT INCLUDE DIR";
41 | fi
42 | if [ $(commandExist 'brew') == "1" ]; then
43 | if [ -d "/opt/homebrew" ]; then
44 | MACOS_LIB_INCLUDE_DIR="/opt/homebrew"
45 | echo "CHOOSE MACOS HOMEBREW /opt/homebrew";
46 | else
47 | MACOS_LIB_INCLUDE_DIR="/usr/local"
48 | echo "CHOOSE MACOS HOMEBREW /usr/local";
49 | fi
50 | fi
51 | if [ $(commandExist 'port') == "1" ]; then
52 | echo "...";
53 | elif [ $(commandExist 'brew') == "1" ]; then
54 | echo "...";
55 | else
56 | echo 'ERROR: homebrew or macport is not installed'
57 | fi
58 | fi
59 |
60 | LINUX_LIB_INCLUDE_DIR="/usr"
61 |
62 |
63 | LINUX_PKG_CONFIG=$'prefix='"$LINUX_LIB_INCLUDE_DIR"'
64 | exec_prefix=${prefix}
65 | includedir=${prefix}/include
66 | libdir=${exec_prefix}/lib
67 |
68 | Name: ton_client
69 | Description: ton_client
70 | Version: 1.0.0
71 | Cflags: -I${includedir}
72 | Libs: -L${libdir} -lton_client'
73 |
74 | MACOS_PKG_CONFIG=$'prefix='"$MACOS_LIB_INCLUDE_DIR"'
75 | exec_prefix=${prefix}
76 | includedir=${prefix}/include
77 | libdir=${exec_prefix}/lib
78 |
79 | Name: ton_client
80 | Description: ton_client
81 | Version: 1.0.0
82 | Cflags: -I${includedir}
83 | Libs: -L${libdir} -lton_client'
84 |
85 | HEADER="$(pwd)/ton_client/tonclient.h"
86 |
87 | echo ""
88 | if [[ -f "$HEADER" ]]; then
89 | echo "CHECK: $HEADER - EXIST"
90 | else
91 | echo ""
92 | echo "ERROR: $HEADER - FILE NOT FOUND"
93 | exit 1;
94 | fi
95 |
96 | if [[ -f "./libton_client.pc" ]]; then
97 | rm ./libton_client.pc
98 | else
99 | echo "OK: libton_client.pc already deleted"
100 | fi
101 |
102 | if [ `uname -s` = Linux ]; then
103 | echo ""
104 | echo "Create symbolic link tonclient.h"
105 | if [[ -h "${LINUX_LIB_INCLUDE_DIR}/include/tonclient.h" ]]; then
106 | sudo rm ${LINUX_LIB_INCLUDE_DIR}/include/tonclient.h
107 | echo "OK: ${LINUX_LIB_INCLUDE_DIR}/include/tonclient.h old symlink already deleted and will create new"
108 | fi
109 | sudo ln -s $HEADER ${LINUX_LIB_INCLUDE_DIR}/include/tonclient.h || echo "ERROR: symbolic link tonclient.h already exist"
110 |
111 | DYLIB="$(pwd)/target/release/libton_client.so"
112 | echo ""
113 | echo "Create symbolic link libton_client.so"
114 | if [ -h "${LINUX_LIB_INCLUDE_DIR}/lib/libton_client.so" ]; then
115 | sudo rm ${LINUX_LIB_INCLUDE_DIR}/lib/libton_client.so
116 | echo "OK: ${LINUX_LIB_INCLUDE_DIR}/lib/libton_client.so old symlink already deleted and will create new"
117 | fi
118 | sudo ln -s $DYLIB ${LINUX_LIB_INCLUDE_DIR}/lib/libton_client.so || echo "ERROR: symbolic link libton_client.so already exist"
119 |
120 |
121 | echo "$LINUX_PKG_CONFIG" >> libton_client.pc
122 | sudo mv libton_client.pc ${LINUX_LIB_INCLUDE_DIR}/lib/pkgconfig/libton_client.pc
123 |
124 |
125 |
126 | elif [ `uname -s` = Darwin ]; then
127 | echo ""
128 | echo "Create symbolic link tonclient.h"
129 | if [[ -h "${MACOS_LIB_INCLUDE_DIR}/include/tonclient.h" ]]; then
130 | sudo rm ${MACOS_LIB_INCLUDE_DIR}/include/tonclient.h
131 | echo "OK: ${MACOS_LIB_INCLUDE_DIR}/include/tonclient.h old symlink deleted and will create new"
132 | fi
133 | echo "$HEADER ${MACOS_LIB_INCLUDE_DIR}/include/tonclient.h"
134 | sudo ln -s $HEADER ${MACOS_LIB_INCLUDE_DIR}/include/tonclient.h || echo "ERROR: symbolic link tonclient.h already exist"
135 |
136 | # if [ `uname -m` = arm64 ]; then
137 | # DYLIB="$(pwd)/target/x86_64-apple-darwin/release/libton_client.dylib"
138 | # else
139 | # DYLIB="$(pwd)/target/release/libton_client.dylib"
140 | # fi
141 | DYLIB="$(pwd)/target/release/libton_client.dylib"
142 | echo ""
143 | echo "Create symbolic link libton_client.dylib"
144 | if [[ -h "${MACOS_LIB_INCLUDE_DIR}/lib/libton_client.dylib" ]]; then
145 | sudo rm ${MACOS_LIB_INCLUDE_DIR}/lib/libton_client.dylib
146 | echo "OK: ${MACOS_LIB_INCLUDE_DIR}/lib/libton_client.dylib old symlink deleted and will create new"
147 | fi
148 | sudo ln -s $DYLIB ${MACOS_LIB_INCLUDE_DIR}/lib/libton_client.dylib || echo "ERROR: symbolic link libton_client.dylib already exist"
149 | echo "${DYLIB} to ${MACOS_LIB_INCLUDE_DIR}/lib/libton_client.dylib"
150 |
151 | echo ""
152 | echo "Copy pc file"
153 | echo "$MACOS_PKG_CONFIG" >> libton_client.pc
154 | sudo mv libton_client.pc ${MACOS_LIB_INCLUDE_DIR}/lib/pkgconfig/libton_client.pc
155 | echo "libton_client.pc to ${MACOS_LIB_INCLUDE_DIR}/lib/pkgconfig/libton_client.pc"
156 | else
157 | echo "I CAN INSTALL ONLY LINUX(DEBIAN / UBUNTU / ...) OR MACOS"
158 | fi
159 |
160 | echo $'\nINSTALLATION SDK COMPLETE'
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------