diff --git a/Podfile b/Podfile index afa40bd8de..fbc6a10096 100644 --- a/Podfile +++ b/Podfile @@ -25,6 +25,7 @@ target 'Trust' do pod 'Crashlytics', '~> 3.10' pod 'Firebase/Core' pod 'Kingfisher', '~> 4.0' + pod 'TrustCore', '~> 0.0.5' pod 'TrustKeystore', '~> 0.4.0' pod 'Branch' # pod 'web3swift', :git=>'https://github.com/BANKEX/web3swift', :branch=>'master' diff --git a/Podfile.lock b/Podfile.lock index f5b8bb8d7e..3053cb3b02 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -18,14 +18,14 @@ PODS: - FirebaseAnalytics (4.1.0): - FirebaseCore (~> 4.0) - FirebaseInstanceID (~> 2.0) - - GoogleToolboxForMac/NSData+zlib (~> 2.1) + - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" - nanopb (~> 0.3) - FirebaseCore (4.0.18): - - GoogleToolboxForMac/NSData+zlib (~> 2.1) + - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" - FirebaseInstanceID (2.0.10): - FirebaseCore (~> 4.0) - GoogleToolboxForMac/Defines (2.1.3) - - GoogleToolboxForMac/NSData+zlib (2.1.3): + - "GoogleToolboxForMac/NSData+zlib (2.1.3)": - GoogleToolboxForMac/Defines (= 2.1.3) - JavaScriptKit (1.0.0): - Result (~> 3.1) @@ -62,7 +62,7 @@ PODS: - StatefulViewController (3.0) - SwiftLint (0.25.0) - TrezorCrypto (0.0.5) - - TrustCore (0.0.4): + - TrustCore (0.0.5): - BigInt - TrezorCrypto - TrustKeystore (0.4.0): @@ -97,10 +97,48 @@ DEPENDENCIES: - SeedStackViewController - StatefulViewController - SwiftLint + - TrustCore (~> 0.0.5) - TrustKeystore (~> 0.4.0) - TrustWeb3Provider (from `https://github.com/TrustWallet/trust-web3-provider`, branch `master`) - URLNavigator +SPEC REPOS: + https://github.com/CocoaPods/Specs.git: + - Alamofire + - APIKit + - BigInt + - Branch + - Crashlytics + - Eureka + - Fabric + - Firebase + - FirebaseAnalytics + - FirebaseCore + - FirebaseInstanceID + - GoogleToolboxForMac + - JavaScriptKit + - JdenticonSwift + - KeychainSwift + - Kingfisher + - Lokalise + - MBProgressHUD + - Moya + - nanopb + - R.swift + - R.swift.Library + - Realm + - RealmSwift + - Result + - SAMKeychain + - SeedStackViewController + - SipHash + - StatefulViewController + - SwiftLint + - TrezorCrypto + - TrustCore + - TrustKeystore + - URLNavigator + EXTERNAL SOURCES: CryptoSwift: :branch: master @@ -163,11 +201,11 @@ SPEC CHECKSUMS: StatefulViewController: 4803bf900d44de26074344998e10e041113b5931 SwiftLint: e14651157288e9e01d6e1a71db7014fb5744a8ea TrezorCrypto: ecef681446bf02af6248d3b5e394026d7e766e56 - TrustCore: 305289e5b1d484d6fe935fc47c724f3ceeae4100 + TrustCore: 6d093f73a0c90ee1944c8f8f77994fcbafccce62 TrustKeystore: 1bd016c67de7314e84b79dba2c22ef64b86bb63e TrustWeb3Provider: 3d5c9f17aa6cc3fcd083d232aed5e90615be5383 URLNavigator: af5582fbbb3586c958be16835d799bfdb23a4793 -PODFILE CHECKSUM: d37ca121b2a933cc7f81a40c8e4e235769baf8a4 +PODFILE CHECKSUM: 4f0582cc1997ca74f067b620931494d91c513670 -COCOAPODS: 1.4.0 +COCOAPODS: 1.5.0 diff --git a/Trust.xcodeproj/project.pbxproj b/Trust.xcodeproj/project.pbxproj index 1c06a7b654..48327948d8 100644 --- a/Trust.xcodeproj/project.pbxproj +++ b/Trust.xcodeproj/project.pbxproj @@ -116,7 +116,6 @@ 2963B6AF1F9823E6003063C1 /* UnconfirmedTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6AE1F9823E6003063C1 /* UnconfirmedTransaction.swift */; }; 2963B6B11F9891F5003063C1 /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6B01F9891F5003063C1 /* UIButton.swift */; }; 2963B6B91F9A7EEA003063C1 /* CoinTicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6B81F9A7EEA003063C1 /* CoinTicker.swift */; }; - 2963B6BF1F9AB9A2003063C1 /* ContractERC20Transfer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6BE1F9AB9A2003063C1 /* ContractERC20Transfer.swift */; }; 2963B6C11F9AE0E4003063C1 /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2963B6C01F9AE0E4003063C1 /* Data.swift */; }; 296421951F70C1EC00EB363B /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296421941F70C1EC00EB363B /* LoadingView.swift */; }; 296421971F70C1F200EB363B /* ErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 296421961F70C1F200EB363B /* ErrorView.swift */; }; @@ -149,8 +148,6 @@ 2996F1461F6C98B3005C33AE /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2996F1451F6C98B3005C33AE /* SettingsViewController.swift */; }; 2996F1481F6C9AE5005C33AE /* SettingsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2996F1471F6C9AE5005C33AE /* SettingsCoordinator.swift */; }; 2996F14D1F6CA743005C33AE /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2996F14C1F6CA742005C33AE /* UIViewController.swift */; }; - 299B5E291FCA8F040051361C /* GetERC20Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B5E281FCA8F040051361C /* GetERC20Balance.swift */; }; - 299B5E2B1FCA9A640051361C /* ApproveERC20.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B5E2A1FCA9A640051361C /* ApproveERC20.swift */; }; 299B5E2D1FCBC0660051361C /* BalanceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B5E2C1FCBC0660051361C /* BalanceProtocol.swift */; }; 299B5E341FCBC5180051361C /* ConfirmPaymentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B5E331FCBC5180051361C /* ConfirmPaymentViewModel.swift */; }; 299B5E381FCBCDF70051361C /* RequestViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299B5E371FCBCDF70051361C /* RequestViewModelTests.swift */; }; @@ -586,7 +583,6 @@ 2963B6AE1F9823E6003063C1 /* UnconfirmedTransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnconfirmedTransaction.swift; sourceTree = ""; }; 2963B6B01F9891F5003063C1 /* UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = ""; }; 2963B6B81F9A7EEA003063C1 /* CoinTicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinTicker.swift; sourceTree = ""; }; - 2963B6BE1F9AB9A2003063C1 /* ContractERC20Transfer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContractERC20Transfer.swift; sourceTree = ""; }; 2963B6C01F9AE0E4003063C1 /* Data.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; 296421941F70C1EC00EB363B /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = ""; }; 296421961F70C1F200EB363B /* ErrorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorView.swift; sourceTree = ""; }; @@ -619,8 +615,6 @@ 2996F1451F6C98B3005C33AE /* SettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; 2996F1471F6C9AE5005C33AE /* SettingsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsCoordinator.swift; sourceTree = ""; }; 2996F14C1F6CA742005C33AE /* UIViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = ""; }; - 299B5E281FCA8F040051361C /* GetERC20Balance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetERC20Balance.swift; sourceTree = ""; }; - 299B5E2A1FCA9A640051361C /* ApproveERC20.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApproveERC20.swift; sourceTree = ""; }; 299B5E2C1FCBC0660051361C /* BalanceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BalanceProtocol.swift; sourceTree = ""; }; 299B5E331FCBC5180051361C /* ConfirmPaymentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmPaymentViewModel.swift; sourceTree = ""; }; 299B5E371FCBCDF70051361C /* RequestViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestViewModelTests.swift; sourceTree = ""; }; @@ -1159,9 +1153,6 @@ isa = PBXGroup; children = ( 291795001F95F5E200539A30 /* GetBalance.swift */, - 2963B6BE1F9AB9A2003063C1 /* ContractERC20Transfer.swift */, - 299B5E281FCA8F040051361C /* GetERC20Balance.swift */, - 299B5E2A1FCA9A640051361C /* ApproveERC20.swift */, ); path = Commands; sourceTree = ""; @@ -2605,8 +2596,6 @@ 2912CD071F6A830700C6CBE3 /* Sources */, 2912CD081F6A830700C6CBE3 /* Frameworks */, 2912CD091F6A830700C6CBE3 /* Resources */, - 21113C0DD6E65F7B19B7168D /* [CP] Embed Pods Frameworks */, - 1C9163CAD4D9FEA04F88B1B8 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -2626,8 +2615,6 @@ 2912CD121F6A830700C6CBE3 /* Sources */, 2912CD131F6A830700C6CBE3 /* Frameworks */, 2912CD141F6A830700C6CBE3 /* Resources */, - EE4505A9D0560D5774C59C3B /* [CP] Embed Pods Frameworks */, - 8179B50383DC9D917751421B /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -2790,36 +2777,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1C9163CAD4D9FEA04F88B1B8 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TrustTests/Pods-TrustTests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 21113C0DD6E65F7B19B7168D /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TrustTests/Pods-TrustTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 2909B06A324FDD6FB858F676 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2897,21 +2854,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 8179B50383DC9D917751421B /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Copy Pods Resources"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TrustUITests/Pods-TrustUITests-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; EB2D49CBEF37022D8861D8E0 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -2930,21 +2872,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - EE4505A9D0560D5774C59C3B /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-TrustUITests/Pods-TrustUITests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; F291FF6299FBB0600050DA49 /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -3236,7 +3163,6 @@ BB3B86BD204CE9730061FCBA /* URLNavigatorCoordinator.swift in Sources */, 732C51462062B625007134C7 /* ScriptMessageProxy.swift in Sources */, 29B933F81F8609FF009FCABB /* PaymentFlow.swift in Sources */, - 2963B6BF1F9AB9A2003063C1 /* ContractERC20Transfer.swift in Sources */, 29A13E331F6B1B7A00E432A2 /* AppStyle.swift in Sources */, 737EEDDA201BE3A8009D9D5D /* Lock.swift in Sources */, 29FF12F81F747D6C00AFD326 /* Error.swift in Sources */, @@ -3270,7 +3196,6 @@ 2912CD2B1F6A833E00C6CBE3 /* TransactionsViewController.swift in Sources */, 775C00B520195BFB001B5EBC /* BrowserAction.swift in Sources */, BB5D6A9E20232EE8000FC5AB /* CurrencyRate+Fee.swift in Sources */, - 299B5E291FCA8F040051361C /* GetERC20Balance.swift in Sources */, 77E0E773201FAD06009B4B31 /* BrowserURLParser.swift in Sources */, 73ACEF0520163F46003DD71D /* LockEnterPasscodeCoordinator.swift in Sources */, 29F1C863200375D2003780D8 /* Wallet.swift in Sources */, @@ -3329,7 +3254,6 @@ 291F52B71F6B870400B369AB /* CastError.swift in Sources */, 664D11A12007D59F0041A0B0 /* EstimateGasRequest.swift in Sources */, 293248841F88CCD2008A9818 /* SplashState.swift in Sources */, - 299B5E2B1FCA9A640051361C /* ApproveERC20.swift in Sources */, 771A847320322F2500528D28 /* PreferencesViewController.swift in Sources */, 291794FB1F95DC2200539A30 /* Web3Swift.swift in Sources */, 29DBF2A31F9DBFF400327C60 /* BackupCoordinator.swift in Sources */, diff --git a/Trust/Tokens/Coordinators/TokensBalanceService.swift b/Trust/Tokens/Coordinators/TokensBalanceService.swift index 927dec080f..45397030eb 100644 --- a/Trust/Tokens/Coordinators/TokensBalanceService.swift +++ b/Trust/Tokens/Coordinators/TokensBalanceService.swift @@ -22,37 +22,22 @@ class TokensBalanceService { contract: Address, completion: @escaping (Result) -> Void ) { - let request = GetERC20BalanceEncode(address: address) - web3.request(request: request) { result in - switch result { - case .success(let res): - let request2 = EtherServiceRequest( - batch: BatchFactory().create(CallRequest(to: contract.description, data: res)) - ) - Session.send(request2) { [weak self] result2 in - switch result2 { - case .success(let balance): - let request = GetERC20BalanceDecode(data: balance) - self?.web3.request(request: request) { result in - switch result { - case .success(let res): - completion(.success(BigInt(res) ?? BigInt())) - case .failure(let error): - NSLog("getPrice3 error \(error)") - completion(.failure(AnyError(error))) - } - } - case .failure(let error): - NSLog("getPrice2 error \(error)") - completion(.failure(AnyError(error))) - } - } + let encoded = ERC20Encoder.encodeBalanceOf(address: address) + let request2 = EtherServiceRequest( + batch: BatchFactory().create(CallRequest(to: contract.description, data: encoded.hexString)) + ) + Session.send(request2) { result2 in + switch result2 { + case .success(let balance): + let biguint = BigUInt(Data(hex: balance)) + completion(.success(BigInt(sign: .plus, magnitude: biguint))) case .failure(let error): - NSLog("getPrice error \(error)") + NSLog("getPrice2 error \(error)") completion(.failure(AnyError(error))) } } } + func getEthBalance( for address: Address, completion: @escaping (Result) -> Void diff --git a/Trust/Transfer/Controllers/TransactionConfigurator.swift b/Trust/Transfer/Controllers/TransactionConfigurator.swift index e6f8c5c47d..48b3b7e40e 100644 --- a/Trust/Transfer/Controllers/TransactionConfigurator.swift +++ b/Trust/Transfer/Controllers/TransactionConfigurator.swift @@ -87,22 +87,14 @@ class TransactionConfigurator { ) completion(.success(())) case .token: - session.web3.request(request: ContractERC20Transfer(amount: transaction.value, address: transaction.to!.description)) { [weak self] result in - guard let `self` = self else { return } - switch result { - case .success(let res): - let data = Data(hex: res.drop0x) - self.configuration = TransactionConfiguration( - gasPrice: self.calculatedGasPrice, - gasLimit: GasLimitConfiguration.tokenTransfer, - data: data, - nonce: self.configuration.nonce - ) - completion(.success(())) - case .failure(let error): - completion(.failure(error)) - } - } + let encoded = ERC20Encoder.encodeTransfer(to: transaction.to!, tokens: transaction.value.magnitude) + self.configuration = TransactionConfiguration( + gasPrice: self.calculatedGasPrice, + gasLimit: GasLimitConfiguration.tokenTransfer, + data: encoded, + nonce: self.configuration.nonce + ) + completion(.success(())) case .dapp: guard requestEstimateGas else { return completion(.success(())) diff --git a/Trust/Vendors/New Group/Commands/ApproveERC20.swift b/Trust/Vendors/New Group/Commands/ApproveERC20.swift deleted file mode 100644 index 0f74f015c3..0000000000 --- a/Trust/Vendors/New Group/Commands/ApproveERC20.swift +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright SIX DAY LLC. All rights reserved. - -import Foundation -import BigInt -import TrustCore - -struct ApproveERC20Encode: Web3Request { - typealias Response = String - - static let abi = "{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}" - - let address: Address - let value: BigInt - - var type: Web3RequestType { - let run = "web3.eth.abi.encodeFunctionCall(\(ApproveERC20Encode.abi), [\"\(address.description)\", \"\(value.description)\"])" - return .script(command: run) - } -} diff --git a/Trust/Vendors/New Group/Commands/ContractERC20Transfer.swift b/Trust/Vendors/New Group/Commands/ContractERC20Transfer.swift deleted file mode 100644 index e8a0d68c02..0000000000 --- a/Trust/Vendors/New Group/Commands/ContractERC20Transfer.swift +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright SIX DAY LLC. All rights reserved. - -import Foundation -import BigInt - -struct ContractERC20Transfer: Web3Request { - typealias Response = String - - let amount: BigInt - let address: String - - var type: Web3RequestType { - let run = "web3.eth.abi.encodeFunctionCall({\"constant\": false, \"inputs\": [ { \"name\": \"_to\", \"type\": \"address\" }, { \"name\": \"_value\", \"type\": \"uint256\" } ], \"name\": \"transfer\", \"outputs\": [ { \"name\": \"success\", \"type\": \"bool\" } ], \"type\": \"function\"} , [\"\(address)\", \"\(amount.description)\"])" - return .script(command: run) - } -} diff --git a/Trust/Vendors/New Group/Commands/GetERC20Balance.swift b/Trust/Vendors/New Group/Commands/GetERC20Balance.swift deleted file mode 100644 index d24008d6b5..0000000000 --- a/Trust/Vendors/New Group/Commands/GetERC20Balance.swift +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright SIX DAY LLC. All rights reserved. - -import Foundation -import TrustCore - -struct GetERC20BalanceEncode: Web3Request { - typealias Response = String - - static let abi = "{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}" - - let address: Address - - var type: Web3RequestType { - let run = "web3.eth.abi.encodeFunctionCall(\(GetERC20BalanceEncode.abi), [\"\(address.description)\"])" - return .script(command: run) - } -} - -struct GetERC20BalanceDecode: Web3Request { - typealias Response = String - - let data: String - - var type: Web3RequestType { - let run = "web3.eth.abi.decodeParameter('uint', '\(data)')" - return .script(command: run) - } -}