diff --git a/.github/workflows/macOS-12.yml b/.github/workflows/macOS-tests.yml similarity index 74% rename from .github/workflows/macOS-12.yml rename to .github/workflows/macOS-tests.yml index f94e4be06..9c842cd4f 100644 --- a/.github/workflows/macOS-12.yml +++ b/.github/workflows/macOS-tests.yml @@ -6,7 +6,6 @@ on: - master - develop - hotfix - - unstable paths: - Packag*.swift - web3swift.podspec @@ -20,6 +19,8 @@ on: - master - develop - unstable + # Temporary develop-X.Y.Z branches may be added and removed from here as we release new versions + - develop-4.0 env: DEVELOPER_DIR: /Applications/Xcode_14.1.app/Contents/Developer @@ -32,7 +33,12 @@ jobs: group: spm-${{ github.run_id }} cancel-in-progress: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 + - name: Discover typos + run: | + pip3 install --upgrade pip + pip3 install codespell + codespell --count --ignore-words-list=ans,deriver,inout,packag --skip="*.js,*WordLists.swift" - name: Resolve dependencies run: swift package resolve - name: Build diff --git a/CHANGELOG.md b/CHANGELOG.md index 6da5dbfb2..d1fef400b 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,7 +83,7 @@ - `subscribeOnLogs` method with specific contract address is not working!!!! [\#366](https://github.com/skywinder/web3swift/issues/366) - EthereumContract with Custom ABI returns nil [\#342](https://github.com/skywinder/web3swift/issues/342) - Error on running tests [\#290](https://github.com/skywinder/web3swift/issues/290) -- Serialisation of BIP32 misplaced address postition [\#257](https://github.com/skywinder/web3swift/issues/257) +- Serialisation of BIP32 misplaced address position [\#257](https://github.com/skywinder/web3swift/issues/257) - Xcode 10.2.1 carthage update hangs while building web3swift.xcodeproj [\#197](https://github.com/skywinder/web3swift/issues/197) **Closed issues:** @@ -118,7 +118,7 @@ - @ravi-ranjan-oodles thanks for the update. [\#329](https://github.com/skywinder/web3swift/issues/329) - Issue in Uploading to Test Flight [\#328](https://github.com/skywinder/web3swift/issues/328) - Update CryptoSwift podspec [\#322](https://github.com/skywinder/web3swift/issues/322) -- cann't open DApp, such as "https://uniswap.tokenpocket.pro/\#/swap" [\#321](https://github.com/skywinder/web3swift/issues/321) +- can't open DApp, such as "https://uniswap.tokenpocket.pro/\#/swap" [\#321](https://github.com/skywinder/web3swift/issues/321) - CryptoSwift version is too low to work properly in Xcode12.5 [\#318](https://github.com/skywinder/web3swift/issues/318) - web3swift.Web3Error.processingError\(desc: "Failed to fetch gas estimate"\)(BSC Chain) [\#317](https://github.com/skywinder/web3swift/issues/317) - Quick simple steps for minting ERC20 or ERC721 tokens [\#314](https://github.com/skywinder/web3swift/issues/314) @@ -126,7 +126,7 @@ - I can't find func 'Web3.InfuraKovanWeb3\(\)' [\#311](https://github.com/skywinder/web3swift/issues/311) - web3 instance error: Variable used within its own initial value [\#310](https://github.com/skywinder/web3swift/issues/310) - Failed to fetch gas estimate when sending erc20 [\#307](https://github.com/skywinder/web3swift/issues/307) -- DApp browser cann't open Uniswap in a right way [\#304](https://github.com/skywinder/web3swift/issues/304) +- DApp browser can't open Uniswap in a right way [\#304](https://github.com/skywinder/web3swift/issues/304) - Update cocoapods bigint to 5.0 [\#288](https://github.com/skywinder/web3swift/issues/288) - When I use getBlockByNumber , hash Unable to check [\#287](https://github.com/skywinder/web3swift/issues/287) - How to parse the return value of read transaction [\#284](https://github.com/skywinder/web3swift/issues/284) @@ -231,7 +231,7 @@ - policy [\#247](https://github.com/skywinder/web3swift/pull/247) ([BaldyAsh](https://github.com/BaldyAsh)) - Fix dependencies, build [\#245](https://github.com/skywinder/web3swift/pull/245) ([BaldyAsh](https://github.com/BaldyAsh)) - chore: update ENS Registry migration [\#243](https://github.com/skywinder/web3swift/pull/243) ([aranhaagency](https://github.com/aranhaagency)) -- improtant notice update [\#232](https://github.com/skywinder/web3swift/pull/232) ([skywinder](https://github.com/skywinder)) +- important notice update [\#232](https://github.com/skywinder/web3swift/pull/232) ([skywinder](https://github.com/skywinder)) - Add Alice Wallet to project list [\#230](https://github.com/skywinder/web3swift/pull/230) ([lmcmz](https://github.com/lmcmz)) - Update Extensions.swift [\#225](https://github.com/skywinder/web3swift/pull/225) ([kocherovets](https://github.com/kocherovets)) - correct gasLimit [\#222](https://github.com/skywinder/web3swift/pull/222) ([luqz](https://github.com/luqz)) @@ -249,10 +249,10 @@ **Closed issues:** - BigInt 3.1 [\#207](https://github.com/skywinder/web3swift/issues/207) -- recevied transaction id from geth node server but not able to see that transaction id at etherscan.io [\#200](https://github.com/skywinder/web3swift/issues/200) +- received transaction id from geth node server but not able to see that transaction id at etherscan.io [\#200](https://github.com/skywinder/web3swift/issues/200) - How do I fetch information such as balance, decimal,symbol and name of ERC20token ? [\#199](https://github.com/skywinder/web3swift/issues/199) - Starscream 3.1.0 not compatible with Swift 5.0 [\#195](https://github.com/skywinder/web3swift/issues/195) -- How to Connect infuraWebsocket and subsribe perticular event in swift? [\#193](https://github.com/skywinder/web3swift/issues/193) +- How to Connect infuraWebsocket and subsribe particular event in swift? [\#193](https://github.com/skywinder/web3swift/issues/193) - Use of unresolved identifier 'Wallet' [\#192](https://github.com/skywinder/web3swift/issues/192) - V in Signed Message Hash not being calculated properly [\#191](https://github.com/skywinder/web3swift/issues/191) - Not possible to calculate fast, normal and cheap transaction fee ? [\#190](https://github.com/skywinder/web3swift/issues/190) diff --git a/Example/myWeb3Wallet/myWeb3Wallet/ViewControllers/WalletController/WalletViewController.swift b/Example/myWeb3Wallet/myWeb3Wallet/ViewControllers/WalletController/WalletViewController.swift index 1326f3e7a..c766c5758 100644 --- a/Example/myWeb3Wallet/myWeb3Wallet/ViewControllers/WalletController/WalletViewController.swift +++ b/Example/myWeb3Wallet/myWeb3Wallet/ViewControllers/WalletController/WalletViewController.swift @@ -89,13 +89,13 @@ class WalletViewController: UIViewController { let manager = KeystoreManager([myWeb3KeyStore]) let address = keystore?.addresses?.first #if DEBUG - print("Address :::>>>>> ", address as Any) - print("Address :::>>>>> ", manager.addresses as Any) + print("Address :::>>>>> ", address) + print("Address :::>>>>> ", manager.addresses) #endif let walletAddress = manager.addresses?.first?.address self.walletAddressLabel.text = walletAddress ?? "0x" - print(walletAddress as Any) + print(walletAddress) } else { print("error") } @@ -115,7 +115,7 @@ class WalletViewController: UIViewController { } func importWalletWith(mnemonics: String) { let walletAddress = try? BIP32Keystore(mnemonics: mnemonics , prefixPath: "m/44'/77777'/0'/0") - print(walletAddress?.addresses as Any) + print(walletAddress?.addresses) self.walletAddressLabel.text = "\(walletAddress?.addresses?.first?.address ?? "0x")" } @@ -137,7 +137,7 @@ extension WalletViewController { self._mnemonics = tMnemonics print(_mnemonics) let tempWalletAddress = try? BIP32Keystore(mnemonics: self._mnemonics , prefixPath: "m/44'/77777'/0'/0") - print(tempWalletAddress?.addresses?.first?.address as Any) + print(tempWalletAddress?.addresses?.first?.address) guard let walletAddress = tempWalletAddress?.addresses?.first else { self.showAlertMessage(title: "", message: "We are unable to create wallet", actionName: "Ok") return @@ -145,7 +145,7 @@ extension WalletViewController { self._walletAddress = walletAddress.address let privateKey = try tempWalletAddress?.UNSAFE_getPrivateKeyData(password: "", account: walletAddress) #if DEBUG - print(privateKey as Any, "Is the private key") + print(privateKey, "Is the private key") #endif let keyData = try? JSONEncoder().encode(tempWalletAddress?.keystoreParams) FileManager.default.createFile(atPath: userDir + "/keystore"+"/key.json", contents: keyData, attributes: nil) diff --git a/README.md b/README.md index 92c686767..f7f7187be 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # web3swift **web3swift** is an iOS toolbelt for interaction with the Ethereum network. -## Social medias +## Social media [Join our discord](https://discord.gg/8bHCNmhS7x) or [Telegram](https://t.me/web3swift) if you need support or want to contribute to web3swift development! ![matter-github-swift](https://github.com/web3swift-team/web3swift/blob/develop/web3swift-logo.png) @@ -19,8 +19,8 @@ - [Core features](#core-features) - [Installation](#installation) - - [CocoaPods](#cocoapods) - [Swift Package](#swift-package) + - [CocoaPods](#cocoapods) - [Example usage](#example-usage) - [Send Ether](#send-ether) - [Contract read method](#contract-read-method) @@ -57,7 +57,7 @@ - [x] 🕵️‍♂️ Possibility to **add or remove "middleware" that intercepts**, modifies and even **cancel transaction** workflow on stages "before assembly", "after assembly" and "before submission" - [x] ✅**Literally following the standards** (BIP, EIP, etc): - [x] **[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) (HD Wallets), [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) (Seed phrases), [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) (Key generation prefixes)** -- [x] **[EIP-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)** (Standart interface for tokens - ERC-20), **[EIP-67](https://github.com/ethereum/EIPs/issues/67)** (Standard URI scheme), **[EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md)** (Replay attacks protection), **[EIP-2718](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md)** (Typed Transaction Envelope), **[EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md)** (Gas Fee market change) +- [x] **[EIP-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)** (Standard interface for tokens - ERC-20), **[EIP-67](https://github.com/ethereum/EIPs/issues/67)** (Standard URI scheme), **[EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md)** (Replay attacks protection), **[EIP-2718](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md)** (Typed Transaction Envelope), **[EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md)** (Gas Fee market change) - [x] **And many others** *(For details about this EIP's look at [Documentation page](https://github.com/web3swift-team/web3swift/blob/master/Documentation/))*: EIP-681, EIP-721, EIP-165, EIP-777, EIP-820, EIP-888, EIP-1400, EIP-1410, EIP-1594, EIP-1643, EIP-1644, EIP-1633, EIP-721, EIP-1155, EIP-1376, ST-20 - [x] **RLP encoding** - [x] Base58 encoding scheme @@ -66,6 +66,27 @@ ## Installation +### Swift Package (Recommended) +The [Swift Package Manager](https://swift.org/package-manager/ "") is a tool for automating the distribution of Swift code that is well integrated with Swift build system. + +Once you have your Swift package set up, adding `web3swift` as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. +```swift +dependencies: [ + .package(url: "https://github.com/web3swift-team/web3swift.git", .upToNextMajor(from: "3.0.0")) +] +``` + +Or if your project is not a package follow these guidelines on [how to add a Swift Package to your Xcode project](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app). + + +## Example usage +In the imports section: + +```swift +import web3swift +import Web3Core +``` + ### CocoaPods [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command: @@ -91,23 +112,7 @@ Then, run the following command: $ pod install ``` -### Swift Package -The [Swift Package Manager](https://swift.org/package-manager/ "") is a tool for automating the distribution of Swift code and is integrated into the swift compiler. - -Once you have your Swift package set up, adding Alamofire as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. -```swift -dependencies: [ - .package(url: "https://github.com/web3swift-team/web3swift.git", .upToNextMajor(from: "3.0.0")) -] -``` - -## Example usage -In the imports section: - -```swift -import web3swift -import Web3Core -``` +> **WARNING**: CocoaPods is a powerful tool for managing dependencies in iOS development, but it also has some limitations that preventing us of providing first class support there. We highly recommend using SPM first as using CocoaPods will delay new updates and bug fixes being delivered to you. ### Send Ether ```swift @@ -132,7 +137,7 @@ let response = try await readTX.callContractMethod() let abiString = "[]" // some ABI string let bytecode = Data.fromHex("") // some ABI bite sequence let contract = web3.contract(abiString, at: nil, abiVersion: 2)! -let parameters = [...] as [AnyObject] +let parameters: [Any] = [...] let deployOp = contract.prepareDeploy(bytecode: bytecode, constructor: contract.contract.constructor, parameters: parameters)! deployOp.transaction.from = "" // your address deployOp.transaction.gasLimitPolicy = .manual(3000000) diff --git a/Sources/Core/EthereumABI/ABIElements.swift b/Sources/Core/EthereumABI/ABIElements.swift deleted file mode 100755 index c947f6159..000000000 --- a/Sources/Core/EthereumABI/ABIElements.swift +++ /dev/null @@ -1,394 +0,0 @@ -// -// Created by Alex Vlasov on 25/10/2018. -// Copyright © 2018 Alex Vlasov. All rights reserved. -// - -import Foundation -import BigInt - -public extension ABI { - struct Input: Decodable { - public var name: String? - public var type: String - public var indexed: Bool? - public var components: [Input]? - } - - struct Output: Decodable { - public var name: String? - public var type: String - public var components: [Output]? - } - - struct Record: Decodable { - public var name: String? - public var type: String? - public var payable: Bool? - public var constant: Bool? - public var stateMutability: String? - public var inputs: [ABI.Input]? - public var outputs: [ABI.Output]? - public var anonymous: Bool? - } - - enum Element { - public enum ArraySize { // bytes for convenience - case staticSize(UInt64) - case dynamicSize - case notArray - } - - case function(Function) - case constructor(Constructor) - case fallback(Fallback) - case event(Event) - case receive(Receive) - case error(EthError) - - public enum StateMutability { - case payable - case mutating - case view - case pure - - var isConstant: Bool { - switch self { - case .payable: - return false - case .mutating: - return false - default: - return true - } - } - - var isPayable: Bool { - switch self { - case .payable: - return true - default: - return false - } - } - } - - public struct InOut { - public let name: String - public let type: ParameterType - - public init(name: String, type: ParameterType) { - self.name = name - self.type = type - } - } - - public struct Function { - public let name: String? - public let inputs: [InOut] - public let outputs: [InOut] - public let stateMutability: StateMutability? = nil - public let constant: Bool - public let payable: Bool - - public init(name: String?, inputs: [InOut], outputs: [InOut], constant: Bool, payable: Bool) { - self.name = name - self.inputs = inputs - self.outputs = outputs - self.constant = constant - self.payable = payable - } - } - - public struct Constructor { - public let inputs: [InOut] - public let constant: Bool - public let payable: Bool - public init(inputs: [InOut], constant: Bool, payable: Bool) { - self.inputs = inputs - self.constant = constant - self.payable = payable - } - } - - public struct Fallback { - public let constant: Bool - public let payable: Bool - - public init(constant: Bool, payable: Bool) { - self.constant = constant - self.payable = payable - } - } - - public struct Event { - public let name: String - public let inputs: [Input] - public let anonymous: Bool - - public init(name: String, inputs: [Input], anonymous: Bool) { - self.name = name - self.inputs = inputs - self.anonymous = anonymous - } - - public struct Input { - public let name: String - public let type: ParameterType - public let indexed: Bool - - public init(name: String, type: ParameterType, indexed: Bool) { - self.name = name - self.type = type - self.indexed = indexed - } - } - } - public struct Receive { - public let payable: Bool - public let inputs: [InOut] - - public init(inputs: [InOut], payable: Bool) { - self.inputs = inputs - self.payable = payable - } - } - /// Custom structured error type available since solidity 0.8.4 - public struct EthError { - public let name: String - public let inputs: [Input] - - public struct Input { - public let name: String - public let type: ParameterType - - public init(name: String, type: ParameterType) { - self.name = name - self.type = type - } - } - } - } -} - -// MARK: - Function parameters encoding - -extension ABI.Element { - public func encodeParameters(_ parameters: [AnyObject]) -> Data? { - switch self { - case .constructor(let constructor): - return constructor.encodeParameters(parameters) - case .event: - return nil - case .fallback: - return nil - case .function(let function): - return function.encodeParameters(parameters) - case .receive: - return nil - case .error: - return nil - } - } -} - -extension ABI.Element.Constructor { - public func encodeParameters(_ parameters: [AnyObject]) -> Data? { - guard parameters.count == inputs.count else { return nil } - return ABIEncoder.encode(types: inputs, values: parameters) - } -} - -extension ABI.Element.Function { - - /// Encode parameters of a given contract method - /// - Parameter parameters: Parameters to pass to Ethereum contract - /// - Returns: Encoded data - public func encodeParameters(_ parameters: [AnyObject]) -> Data? { - guard parameters.count == inputs.count, - let data = ABIEncoder.encode(types: inputs, values: parameters) else { return nil } - return methodEncoding + data - } -} - -// MARK: - Event logs decoding - -extension ABI.Element.Event { - public func decodeReturnedLogs(eventLogTopics: [Data], eventLogData: Data) -> [String: Any]? { - guard let eventContent = ABIDecoder.decodeLog(event: self, eventLogTopics: eventLogTopics, eventLogData: eventLogData) else {return nil} - return eventContent - } -} - -// MARK: - Function input/output decoding - -extension ABI.Element { - public func decodeReturnData(_ data: Data) -> [String: Any]? { - switch self { - case .constructor: - return nil - case .event: - return nil - case .fallback: - return nil - case .function(let function): - return function.decodeReturnData(data) - case .receive: - return nil - case .error: - return nil - } - } - - public func decodeInputData(_ data: Data) -> [String: Any]? { - guard data.count == 0 || data.count % 32 == 4 else { return nil } - - switch self { - case .constructor(let constructor): - return constructor.decodeInputData(data) - case .event: - return nil - case .fallback: - return nil - case .function(let function): - return function.decodeInputData(data) - case .receive: - return nil - case .error: - return nil - } - } -} - -extension ABI.Element.Function { - public func decodeInputData(_ rawData: Data) -> [String: Any]? { - return Core.decodeInputData(rawData, methodEncoding: methodEncoding, inputs: inputs) - } - - public func decodeReturnData(_ data: Data) -> [String: Any]? { - // the response size greater than equal 100 bytes, when read function aborted by "require" statement. - // if "require" statement has no message argument, the response is empty (0 byte). - if data.bytes.count >= 100 { - let check00_31 = BigUInt("08C379A000000000000000000000000000000000000000000000000000000000", radix: 16)! - let check32_63 = BigUInt("0000002000000000000000000000000000000000000000000000000000000000", radix: 16)! - - // check data[00-31] and data[32-63] - if check00_31 == BigUInt(data[0...31]) && check32_63 == BigUInt(data[32...63]) { - // data.bytes[64-67] contains the length of require message - let len = (Int(data.bytes[64])<<24) | (Int(data.bytes[65])<<16) | (Int(data.bytes[66])<<8) | Int(data.bytes[67]) - - let message = String(bytes: data.bytes[68..<(68+len)], encoding: .utf8)! - - var returnArray = [String: Any]() - - // set infomation - returnArray["_abortedByRequire"] = true - returnArray["_errorMessageFromRequire"] = message - - // set empty values - for i in 0 ..< outputs.count { - let name = "\(i)" - returnArray[name] = outputs[i].type.emptyValue - if outputs[i].name != "" { - returnArray[outputs[i].name] = outputs[i].type.emptyValue - } - } - - return returnArray - } - } - - var returnArray = [String: Any]() - - // the "require" statement with no message argument will be caught here - if data.count == 0 && outputs.count == 1 { - let name = "0" - let value = outputs[0].type.emptyValue - returnArray[name] = value - if outputs[0].name != "" { - returnArray[outputs[0].name] = value - } - } else { - guard outputs.count * 32 <= data.count else { return nil } - - var i = 0 - guard let values = ABIDecoder.decode(types: outputs, data: data) else { return nil } - for output in outputs { - let name = "\(i)" - returnArray[name] = values[i] - if output.name != "" { - returnArray[output.name] = values[i] - } - i = i + 1 - } - // set a flag to detect the request succeeded - } - - if returnArray.isEmpty { - return nil - } - - returnArray["_success"] = true - return returnArray - } -} - -extension ABI.Element.Constructor { - public func decodeInputData(_ rawData: Data) -> [String: Any]? { - return Core.decodeInputData(rawData, inputs: inputs) - } -} - -/// Generic input decoding function. -/// - Parameters: -/// - rawData: data to decode. Must match the followin criteria: `data.count == 0 || data.count % 32 == 4`. -/// - methodEncoding: 4 bytes represeting method signature like `0xFFffFFff`. Can be ommited to avoid checking method encoding. -/// - inputs: expected input types. Order must be the same as in function declaration. -/// - Returns: decoded dictionary of input arguments mapped to their indices and arguments' names if these are not empty. -/// If decoding of at least one argument fails, `rawData` size is invalid or `methodEncoding` doesn't match - `nil` is returned. -private func decodeInputData(_ rawData: Data, - methodEncoding: Data? = nil, - inputs: [ABI.Element.InOut]) -> [String: Any]? { - let data: Data - let sig: Data? - - switch rawData.count % 32 { - case 0: - sig = nil - data = Data() - break - case 4: - sig = rawData[0 ..< 4] - data = Data(rawData[4 ..< rawData.count]) - default: - return nil - } - - if methodEncoding != nil && sig != nil && sig != methodEncoding { - return nil - } - - var returnArray = [String: Any]() - - if data.count == 0 && inputs.count == 1 { - let name = "0" - let value = inputs[0].type.emptyValue - returnArray[name] = value - if inputs[0].name != "" { - returnArray[inputs[0].name] = value - } - } else { - guard inputs.count * 32 <= data.count else { return nil } - - var i = 0 - guard let values = ABIDecoder.decode(types: inputs, data: data) else {return nil} - for input in inputs { - let name = "\(i)" - returnArray[name] = values[i] - if input.name != "" { - returnArray[input.name] = values[i] - } - i = i + 1 - } - } - return returnArray -} diff --git a/Sources/Web3Core/Contract/ContractProtocol.swift b/Sources/Web3Core/Contract/ContractProtocol.swift index 9302cbc8e..06e3c01a7 100755 --- a/Sources/Web3Core/Contract/ContractProtocol.swift +++ b/Sources/Web3Core/Contract/ContractProtocol.swift @@ -35,7 +35,7 @@ import BigInt /// let inputArgsTypes: [ABI.Element.InOut] = [.init(name: "firstArgument", type: ABI.Element.ParameterType.string), /// .init(name: "secondArgument", type: ABI.Element.ParameterType.uint(bits: 256))] /// let constructor = ABI.Element.Constructor(inputs: inputArgsTypes, constant: false, payable: payable) -/// let constructorArguments = ["This is the array of constructor arguments", 10_000] as [AnyObject] +/// let constructorArguments: [Any] = ["This is the array of constructor arguments", 10_000] /// /// contract.deploy(bytecode: smartContractBytecode, /// constructor: constructor, @@ -48,7 +48,7 @@ import BigInt /// /// ```swift /// let contract = EthereumContract(abiString) -/// let constructorArguments = ["This is the array of constructor arguments", 10_000] as [AnyObject] +/// let constructorArguments: [Any] = ["This is the array of constructor arguments", 10_000] /// /// contract.deploy(bytecode: smartContractBytecode, /// constructor: contract.constructor, @@ -116,12 +116,12 @@ public protocol ContractProtocol { /// - bytecode: bytecode to deploy. /// - constructor: constructor of the smart contract bytecode is related to. Used to encode `parameters`. /// - parameters: parameters for `constructor`. - /// - extraData: any extra data. It can be encoded input arguments for a constuctor but then you should set `constructor` and + /// - extraData: any extra data. It can be encoded input arguments for a constructor but then you should set `constructor` and /// `parameters` to be `nil`. /// - Returns: Encoded data for a given parameters, which is should be assigned to ``CodableTransaction.data`` property func deploy(bytecode: Data, constructor: ABI.Element.Constructor?, - parameters: [AnyObject]?, + parameters: [Any]?, extraData: Data?) -> Data? /// Creates function call transaction with data set as `method` encoded with given `parameters`. @@ -134,7 +134,7 @@ public protocol ContractProtocol { /// - parameters: method input arguments; /// - extraData: additional data to append at the end of `transaction.data` field; /// - Returns: transaction object if `method` was found and `parameters` were successfully encoded. - func method(_ method: String, parameters: [AnyObject], extraData: Data?) -> Data? + func method(_ method: String, parameters: [Any], extraData: Data?) -> Data? /// Decode output data of a function. /// - Parameters: @@ -185,12 +185,12 @@ public protocol ContractProtocol { extension ContractProtocol { /// Overloading of ``ContractProtocol/deploy(bytecode:constructor:parameters:extraData:)`` to allow - /// omitting evertyhing but `bytecode`. + /// omitting everything but `bytecode`. /// /// See ``ContractProtocol/deploy(bytecode:constructor:parameters:extraData:)`` for details. func deploy(_ bytecode: Data, constructor: ABI.Element.Constructor? = nil, - parameters: [AnyObject]? = nil, + parameters: [Any]? = nil, extraData: Data? = nil) -> Data? { deploy(bytecode: bytecode, constructor: constructor, @@ -203,7 +203,7 @@ extension ContractProtocol { /// /// See ``ContractProtocol/method(_:parameters:extraData:)`` for details. func method(_ method: String = "fallback", - parameters: [AnyObject]? = nil, + parameters: [Any]? = nil, extraData: Data? = nil) -> Data? { self.method(method, parameters: parameters ?? [], extraData: extraData) } @@ -222,7 +222,7 @@ extension DefaultContractProtocol { // MARK: Writing Data flow public func deploy(bytecode: Data, constructor: ABI.Element.Constructor?, - parameters: [AnyObject]?, + parameters: [Any]?, extraData: Data?) -> Data? { var fullData = bytecode @@ -258,7 +258,7 @@ extension DefaultContractProtocol { /// - data: parameters + extraData /// - params: EthereumParameters with no contract method call encoded data. public func method(_ method: String, - parameters: [AnyObject], + parameters: [Any], extraData: Data?) -> Data? { // MARK: - Encoding ABI Data flow if method == "fallback" { diff --git a/Sources/Web3Core/EthereumABI/ABIDecoding.swift b/Sources/Web3Core/EthereumABI/ABIDecoding.swift index 7dad9179f..d03a0adb4 100755 --- a/Sources/Web3Core/EthereumABI/ABIDecoding.swift +++ b/Sources/Web3Core/EthereumABI/ABIDecoding.swift @@ -9,15 +9,15 @@ import BigInt public struct ABIDecoder { } extension ABIDecoder { - public static func decode(types: [ABI.Element.InOut], data: Data) -> [AnyObject]? { + public static func decode(types: [ABI.Element.InOut], data: Data) -> [Any]? { let params = types.compactMap { el -> ABI.Element.ParameterType in return el.type } return decode(types: params, data: data) } - public static func decode(types: [ABI.Element.ParameterType], data: Data) -> [AnyObject]? { - var toReturn = [AnyObject]() + public static func decode(types: [ABI.Element.ParameterType], data: Data) -> [Any]? { + var toReturn = [Any]() var consumed: UInt64 = 0 for i in 0 ..< types.count { let (v, c) = decodeSingleType(type: types[i], data: data, pointer: consumed) @@ -29,7 +29,7 @@ extension ABIDecoder { return toReturn } - public static func decodeSingleType(type: ABI.Element.ParameterType, data: Data, pointer: UInt64 = 0) -> (value: AnyObject?, bytesConsumed: UInt64?) { + public static func decodeSingleType(type: ABI.Element.ParameterType, data: Data, pointer: UInt64 = 0) -> (value: Any?, bytesConsumed: UInt64?) { let (elData, nextPtr) = followTheData(type: type, data: data, pointer: pointer) guard let elementItself = elData, let nextElementPointer = nextPtr else { return (nil, nil) @@ -40,18 +40,18 @@ extension ABIDecoder { let mod = BigUInt(1) << bits let dataSlice = elementItself[0 ..< 32] let v = BigUInt(dataSlice) % mod - return (v as AnyObject, type.memoryUsage) + return (v, type.memoryUsage) case .int(let bits): guard elementItself.count >= 32 else {break} let mod = BigInt(1) << bits let dataSlice = elementItself[0 ..< 32] let v = BigInt.fromTwosComplement(data: dataSlice) % mod - return (v as AnyObject, type.memoryUsage) + return (v, type.memoryUsage) case .address: guard elementItself.count >= 32 else {break} let dataSlice = elementItself[12 ..< 32] let address = EthereumAddress(dataSlice) - return (address as AnyObject, type.memoryUsage) + return (address, type.memoryUsage) case .bool: guard elementItself.count >= 32 else {break} let dataSlice = elementItself[0 ..< 32] @@ -60,17 +60,17 @@ extension ABIDecoder { v == BigUInt(32) || v == BigUInt(28) || v == BigUInt(1) { - return (true as AnyObject, type.memoryUsage) + return (true, type.memoryUsage) } else if v == BigUInt(35) || v == BigUInt(31) || v == BigUInt(27) || v == BigUInt(0) { - return (false as AnyObject, type.memoryUsage) + return (false, type.memoryUsage) } case .bytes(let length): guard elementItself.count >= 32 else {break} let dataSlice = elementItself[0 ..< length] - return (dataSlice as AnyObject, type.memoryUsage) + return (dataSlice, type.memoryUsage) case .string: guard elementItself.count >= 32 else {break} var dataSlice = elementItself[0 ..< 32] @@ -78,14 +78,14 @@ extension ABIDecoder { guard elementItself.count >= 32+length else {break} dataSlice = elementItself[32 ..< 32 + length] guard let string = String(data: dataSlice, encoding: .utf8) else {break} - return (string as AnyObject, type.memoryUsage) + return (string, type.memoryUsage) case .dynamicBytes: guard elementItself.count >= 32 else {break} var dataSlice = elementItself[0 ..< 32] let length = UInt64(BigUInt(dataSlice)) guard elementItself.count >= 32+length else {break} dataSlice = elementItself[32 ..< 32 + length] - return (dataSlice as AnyObject, nextElementPointer) + return (dataSlice, nextElementPointer) case .array(type: let subType, length: let length): switch type.arraySize { case .dynamicSize: @@ -97,14 +97,14 @@ extension ABIDecoder { guard elementItself.count >= 32 + subType.memoryUsage*length else {break} dataSlice = elementItself[32 ..< 32 + subType.memoryUsage*length] var subpointer: UInt64 = 32 - var toReturn = [AnyObject]() + var toReturn = [Any]() for _ in 0 ..< length { let (v, c) = decodeSingleType(type: subType, data: elementItself, pointer: subpointer) guard let valueUnwrapped = v, let consumedUnwrapped = c else {break} toReturn.append(valueUnwrapped) subpointer = subpointer + consumedUnwrapped } - return (toReturn as AnyObject, type.memoryUsage) + return (toReturn, type.memoryUsage) } else { // in principle is true for tuple[], so will work for string[] too guard elementItself.count >= 32 else {break} @@ -113,7 +113,7 @@ extension ABIDecoder { guard elementItself.count >= 32 else {break} dataSlice = Data(elementItself[32 ..< elementItself.count]) var subpointer: UInt64 = 0 - var toReturn = [AnyObject]() + var toReturn = [Any]() for _ in 0 ..< length { let (v, c) = decodeSingleType(type: subType, data: dataSlice, pointer: subpointer) guard let valueUnwrapped = v, let consumedUnwrapped = c else {break} @@ -124,11 +124,11 @@ extension ABIDecoder { subpointer = consumedUnwrapped // need to go by nextElementPointer } } - return (toReturn as AnyObject, nextElementPointer) + return (toReturn, nextElementPointer) } case .staticSize(let staticLength): guard length == staticLength else {break} - var toReturn = [AnyObject]() + var toReturn = [Any]() var consumed: UInt64 = 0 for _ in 0 ..< length { let (v, c) = decodeSingleType(type: subType, data: elementItself, pointer: consumed) @@ -137,15 +137,15 @@ extension ABIDecoder { consumed = consumed + consumedUnwrapped } if subType.isStatic { - return (toReturn as AnyObject, consumed) + return (toReturn, consumed) } else { - return (toReturn as AnyObject, nextElementPointer) + return (toReturn, nextElementPointer) } case .notArray: break } case .tuple(types: let subTypes): - var toReturn = [AnyObject]() + var toReturn = [Any]() var consumed: UInt64 = 0 for i in 0 ..< subTypes.count { let (v, c) = decodeSingleType(type: subTypes[i], data: elementItself, pointer: consumed) @@ -173,14 +173,14 @@ extension ABIDecoder { } } if type.isStatic { - return (toReturn as AnyObject, consumed) + return (toReturn, consumed) } else { - return (toReturn as AnyObject, nextElementPointer) + return (toReturn, nextElementPointer) } case .function: guard elementItself.count >= 32 else {break} let dataSlice = elementItself[8 ..< 32] - return (dataSlice as AnyObject, type.memoryUsage) + return (dataSlice, type.memoryUsage) } return (nil, nil) } @@ -196,7 +196,7 @@ extension ABIDecoder { let dataSlice = data[pointer ..< pointer + type.memoryUsage] let bn = BigUInt(dataSlice) if bn > UInt64.max || bn >= data.count { - // there are ERC20 contracts that use bytes32 intead of string. Let's be optimistic and return some data + // there are ERC20 contracts that use bytes32 instead of string. Let's be optimistic and return some data if case .string = type { let nextElement = pointer + type.memoryUsage let preambula = BigUInt(32).abiEncode(bits: 256)! @@ -236,7 +236,7 @@ extension ABIDecoder { return inp.type } guard logs.count == indexedInputs.count + 1 else {return nil} - var indexedValues = [AnyObject]() + var indexedValues = [Any]() for i in 0 ..< indexedInputs.count { let data = logs[i+1] let input = indexedInputs[i] diff --git a/Sources/Web3Core/EthereumABI/ABIElements.swift b/Sources/Web3Core/EthereumABI/ABIElements.swift index aadf61b9a..e2ca9202b 100755 --- a/Sources/Web3Core/EthereumABI/ABIElements.swift +++ b/Sources/Web3Core/EthereumABI/ABIElements.swift @@ -174,7 +174,7 @@ public extension ABI { // MARK: - Function parameters encoding extension ABI.Element { - public func encodeParameters(_ parameters: [AnyObject]) -> Data? { + public func encodeParameters(_ parameters: [Any]) -> Data? { switch self { case .constructor(let constructor): return constructor.encodeParameters(parameters) @@ -193,7 +193,7 @@ extension ABI.Element { } extension ABI.Element.Constructor { - public func encodeParameters(_ parameters: [AnyObject]) -> Data? { + public func encodeParameters(_ parameters: [Any]) -> Data? { guard parameters.count == inputs.count else { return nil } return ABIEncoder.encode(types: inputs, values: parameters) } @@ -204,7 +204,7 @@ extension ABI.Element.Function { /// Encode parameters of a given contract method /// - Parameter parameters: Parameters to pass to Ethereum contract /// - Returns: Encoded data - public func encodeParameters(_ parameters: [AnyObject]) -> Data? { + public func encodeParameters(_ parameters: [Any]) -> Data? { guard parameters.count == inputs.count, let data = ABIEncoder.encode(types: inputs, values: parameters) else { return nil } return methodEncoding + data @@ -262,7 +262,7 @@ extension ABI.Element { extension ABI.Element.Function { public func decodeInputData(_ rawData: Data) -> [String: Any]? { - return Web3Core.decodeInputData(rawData, methodEncoding: methodEncoding, inputs: inputs) + return ABIDecoder.decodeInputData(rawData, methodEncoding: methodEncoding, inputs: inputs) } /// Decodes data returned by a function call. Able to decode `revert(string)`, `revert CustomError(...)` and `require(expression, string)` calls. @@ -432,61 +432,63 @@ extension ABI.Element.Function { extension ABI.Element.Constructor { public func decodeInputData(_ rawData: Data) -> [String: Any]? { - return Web3Core.decodeInputData(rawData, inputs: inputs) + return ABIDecoder.decodeInputData(rawData, inputs: inputs) } } -/// Generic input decoding function. -/// - Parameters: -/// - rawData: data to decode. Must match the followin criteria: `data.count == 0 || data.count % 32 == 4`. -/// - methodEncoding: 4 bytes represeting method signature like `0xFFffFFff`. Can be ommited to avoid checking method encoding. -/// - inputs: expected input types. Order must be the same as in function declaration. -/// - Returns: decoded dictionary of input arguments mapped to their indices and arguments' names if these are not empty. -/// If decoding of at least one argument fails, `rawData` size is invalid or `methodEncoding` doesn't match - `nil` is returned. -private func decodeInputData(_ rawData: Data, - methodEncoding: Data? = nil, - inputs: [ABI.Element.InOut]) -> [String: Any]? { - let data: Data - let sig: Data? - - switch rawData.count % 32 { - case 0: - sig = nil - data = Data() - break - case 4: - sig = rawData[0 ..< 4] - data = Data(rawData[4 ..< rawData.count]) - default: - return nil - } +extension ABIDecoder { + /// Generic input decoding function. + /// - Parameters: + /// - rawData: data to decode. Must match the following criteria: `data.count == 0 || data.count % 32 == 4`. + /// - methodEncoding: 4 bytes representing method signature like `0xFFffFFff`. Can be omitted to avoid checking method encoding. + /// - inputs: expected input types. Order must be the same as in function declaration. + /// - Returns: decoded dictionary of input arguments mapped to their indices and arguments' names if these are not empty. + /// If decoding of at least one argument fails, `rawData` size is invalid or `methodEncoding` doesn't match - `nil` is returned. + static func decodeInputData(_ rawData: Data, + methodEncoding: Data? = nil, + inputs: [ABI.Element.InOut]) -> [String: Any]? { + let data: Data + let sig: Data? + + switch rawData.count % 32 { + case 0: + sig = nil + data = Data() + break + case 4: + sig = rawData[0 ..< 4] + data = Data(rawData[4 ..< rawData.count]) + default: + return nil + } - if methodEncoding != nil && sig != nil && sig != methodEncoding { - return nil - } + if methodEncoding != nil && sig != nil && sig != methodEncoding { + return nil + } - var returnArray = [String: Any]() + var returnArray = [String: Any]() - if data.count == 0 && inputs.count == 1 { - let name = "0" - let value = inputs[0].type.emptyValue - returnArray[name] = value - if inputs[0].name != "" { - returnArray[inputs[0].name] = value - } - } else { - guard inputs.count * 32 <= data.count else { return nil } - - var i = 0 - guard let values = ABIDecoder.decode(types: inputs, data: data) else {return nil} - for input in inputs { - let name = "\(i)" - returnArray[name] = values[i] - if input.name != "" { - returnArray[input.name] = values[i] + if data.count == 0 && inputs.count == 1 { + let name = "0" + let value = inputs[0].type.emptyValue + returnArray[name] = value + if inputs[0].name != "" { + returnArray[inputs[0].name] = value + } + } else { + guard inputs.count * 32 <= data.count else { return nil } + + var i = 0 + guard let values = ABIDecoder.decode(types: inputs, data: data) else {return nil} + for input in inputs { + let name = "\(i)" + returnArray[name] = values[i] + if input.name != "" { + returnArray[input.name] = values[i] + } + i = i + 1 } - i = i + 1 } + return returnArray } - return returnArray -} +} \ No newline at end of file diff --git a/Sources/Web3Core/EthereumABI/ABIEncoding.swift b/Sources/Web3Core/EthereumABI/ABIEncoding.swift index f62177ec8..3b61da8c5 100755 --- a/Sources/Web3Core/EthereumABI/ABIEncoding.swift +++ b/Sources/Web3Core/EthereumABI/ABIEncoding.swift @@ -12,7 +12,7 @@ public struct ABIEncoder { /// All negative values will return `nil`. /// - Parameter value: an arbitrary object. /// - Returns: converted value or `nil` if types is not support or initialization failed. - public static func convertToBigUInt(_ value: AnyObject) -> BigUInt? { + public static func convertToBigUInt(_ value: Any) -> BigUInt? { switch value { case let v as BigUInt: return v @@ -60,7 +60,7 @@ public struct ABIEncoder { /// Supported types are `BigUInt`, `BigInt`, `String` as hex and decimal, `UInt[8-64]`, `Int[8-64]` and `Data`. /// - Parameter value: an arbitrary object. /// - Returns: converted value or `nil` if types is not support or initialization failed. - public static func convertToBigInt(_ value: AnyObject) -> BigInt? { + public static func convertToBigInt(_ value: Any) -> BigInt? { switch value { case let v as BigUInt: return BigInt(v) @@ -98,11 +98,11 @@ public struct ABIEncoder { /// Attempts to convert given object into `Data`. /// Used as a part of ABI encoding process. - /// Supported types are `Data`, `String`, `[UInt8]`, ``EthereumAddress`` and `[IntegerLiteralType]`. + /// Supported types are `Data`, `String`, `[UInt8]`, ``EthereumAddress``, `[IntegerLiteralType]` and `Bool`. /// Note: if `String` has `0x` prefix an attempt to interpret it as a hexadecimal number will take place. Otherwise, UTF-8 bytes are returned. /// - Parameter value: any object. /// - Returns: `Data` representation of an object ready for ABI encoding. - public static func convertToData(_ value: AnyObject) -> Data? { + public static func convertToData(_ value: Any) -> Data? { switch value { case let d as Data: return d @@ -123,6 +123,8 @@ public struct ABIEncoder { bytesArray.append(UInt8(el)) } return Data(bytesArray) + case let b as Bool: + return b ? Data([UInt8(1)]) : Data(count: 1) default: return nil } @@ -137,7 +139,7 @@ public struct ABIEncoder { /// - Returns: ABI encoded data, e.g. function call parameters. Returns `nil` if: /// - `types.count != values.count`; /// - encoding of at least one value has failed (e.g. type mismatch). - public static func encode(types: [ABI.Element.InOut], values: [AnyObject]) -> Data? { + public static func encode(types: [ABI.Element.InOut], values: [Any]) -> Data? { guard types.count == values.count else {return nil} let params = types.compactMap { el -> ABI.Element.ParameterType in return el.type @@ -153,7 +155,7 @@ public struct ABIEncoder { /// - Returns: ABI encoded data, e.g. function call parameters. Returns `nil` if: /// - `types.count != values.count`; /// - encoding of at least one value has failed (e.g. type mismatch). - public static func encode(types: [ABI.Element.ParameterType], values: [AnyObject]) -> Data? { + public static func encode(types: [ABI.Element.ParameterType], values: [Any]) -> Data? { guard types.count == values.count else {return nil} var tails = [Data]() var heads = [Data]() @@ -195,7 +197,7 @@ public struct ABIEncoder { /// /// **It does not add the data offset for dynamic types!!** To return single value **with data offset** use the following instead: /// ```swift - /// ABIEncoder.encode(types: [type], values: [value] as [AnyObject]) + /// ABIEncoder.encode(types: [type], values: [value]) /// ``` /// Almost identical to use of `web3.eth.abi.encodeParameter` in web3.js. /// Calling `web3.eth.abi.encodeParameter('string','test')` in web3.js will return the following: @@ -204,7 +206,7 @@ public struct ABIEncoder { /// 0000000000000000000000000000000000000000000000000000000000000004 /// 7465737400000000000000000000000000000000000000000000000000000000 /// ``` - /// but calling `ABIEncoder.encodeSingleType(type: .string, value: "test" as AnyObject)` will return: + /// but calling `ABIEncoder.encodeSingleType(type: .string, value: "test")` will return: /// ``` /// 0x0000000000000000000000000000000000000000000000000000000000000004 /// 7465737400000000000000000000000000000000000000000000000000000000 @@ -215,22 +217,14 @@ public struct ABIEncoder { /// - Returns: ABI encoded data, e.g. function call parameters. Returns `nil` if: /// - `types.count != values.count`; /// - encoding has failed (e.g. type mismatch). - public static func encodeSingleType(type: ABI.Element.ParameterType, value: AnyObject) -> Data? { + public static func encodeSingleType(type: ABI.Element.ParameterType, value: Any) -> Data? { switch type { case .uint: - if let biguint = convertToBigUInt(value) { - return biguint.abiEncode(bits: 256) - } - if let bigint = convertToBigInt(value) { - return bigint.abiEncode(bits: 256) - } + let biguint = convertToBigUInt(value) + return biguint == nil ? nil : biguint!.abiEncode(bits: 256) case .int: - if let biguint = convertToBigUInt(value) { - return biguint.abiEncode(bits: 256) - } - if let bigint = convertToBigInt(value) { - return bigint.abiEncode(bits: 256) - } + let bigint = convertToBigInt(value) + return bigint == nil ? nil : bigint!.abiEncode(bits: 256) case .address: if let string = value as? String { guard let address = EthereumAddress(string) else {return nil} @@ -283,7 +277,7 @@ public struct ABIEncoder { switch type.arraySize { case .dynamicSize: guard length == 0 else {break} - guard let val = value as? [AnyObject] else {break} + guard let val = value as? [Any] else {break} guard let lengthEncoding = BigUInt(val.count).abiEncode(bits: 256) else {break} if subType.isStatic { // work in a previous context @@ -330,7 +324,7 @@ public struct ABIEncoder { } case .staticSize(let staticLength): guard staticLength != 0 else {break} - guard let val = value as? [AnyObject] else {break} + guard let val = value as? [Any] else {break} guard staticLength == val.count else {break} if subType.isStatic { // work in a previous context @@ -375,7 +369,7 @@ public struct ABIEncoder { case .tuple(types: let subTypes): var tails = [Data]() var heads = [Data]() - guard let val = value as? [AnyObject] else {break} + guard let val = value as? [Any] else {break} for i in 0 ..< subTypes.count { let enc = encodeSingleType(type: subTypes[i], value: val[i]) guard let encoding = enc else {return nil} @@ -444,7 +438,7 @@ public extension ABIEncoder { } } - /// Using AnyObject any number can be represented as Bool and Bool can be represented as number. + /// Using Any any number can be represented as Bool and Bool can be represented as number. /// That will lead to invalid hash output. DO NOT USE THIS FUNCTION. /// This function will exist to intentionally throw an error that will raise awareness that the hash output can be potentially, /// and most likely will be, wrong. @@ -471,26 +465,26 @@ public extension ABIEncoder { if let v = value as? Bool { return Data(v ? [0b1] : [0b0]) } else if let v = value as? Int { - return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 256)! as AnyObject)! + return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 256)!)! } else if let v = value as? Int8 { - return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 8) as AnyObject)! + return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 8))! } else if let v = value as? Int16 { - return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 16)! as AnyObject)! + return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 16)!)! } else if let v = value as? Int32 { - return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 32)! as AnyObject)! + return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 32)!)! } else if let v = value as? Int64 { - return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 64)! as AnyObject)! + return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 64)!)! } else if let v = value as? UInt { - return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 256)! as AnyObject)! + return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 256)!)! } else if let v = value as? UInt8 { - return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 8)! as AnyObject)! + return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 8)!)! } else if let v = value as? UInt16 { - return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 16)! as AnyObject)! + return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 16)!)! } else if let v = value as? UInt32 { - return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 32)! as AnyObject)! + return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 32)!)! } else if let v = value as? UInt64 { - return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 64)! as AnyObject)! - } else if let data = ABIEncoder.convertToData(value as AnyObject) { + return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 64)!)! + } else if let data = ABIEncoder.convertToData(value) { return data } throw Web3Error.inputError(desc: "SoliditySha3: `abiEncode` accepts an Int/UInt (any of 8, 16, 32, 64 bits long), decimal or hexadecimal string, Bool, Data, [UInt8], EthereumAddress, [IntegerLiteralType], BigInt or BigUInt instance. Given value is of type \(type(of: value)).") diff --git a/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift b/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift index c13fb9f15..1d2f32744 100644 --- a/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift +++ b/Sources/Web3Core/EthereumABI/Sequence+ABIExtension.swift @@ -63,7 +63,7 @@ public extension Sequence where Element == ABI.Element { /// Filters out ``ABI/Element/Constructor``. /// If there are multiple of them the first encountered will be returned and if there are none a default constructor will be returned /// that accepts no input parameters. - /// - Returns: the first ``ABI/Element/Constructor`` or default contructor with no input parameters. + /// - Returns: the first ``ABI/Element/Constructor`` or default constructor with no input parameters. func getConstructor() -> ABI.Element.Constructor { for case let .constructor(constructor) in self { return constructor diff --git a/Sources/Web3Core/EthereumAddress/EthereumAddress.swift b/Sources/Web3Core/EthereumAddress/EthereumAddress.swift index ba703f78e..2e8d0ef45 100755 --- a/Sources/Web3Core/EthereumAddress/EthereumAddress.swift +++ b/Sources/Web3Core/EthereumAddress/EthereumAddress.swift @@ -91,7 +91,7 @@ public struct EthereumAddress: Equatable { } /// In swift structs it's better to implement initializers in extension -/// Since it's make available syntetized initializer then for free. +/// Since it's make available synthesized initializer then for free. extension EthereumAddress { public init?(_ addressString: String, type: AddressType = .normal, ignoreChecksum: Bool = false) { switch type { diff --git a/Sources/Web3Core/EthereumNetwork/Request/APIRequest.swift b/Sources/Web3Core/EthereumNetwork/Request/APIRequest.swift index 39d9cae4d..cb057da7e 100644 --- a/Sources/Web3Core/EthereumNetwork/Request/APIRequest.swift +++ b/Sources/Web3Core/EthereumNetwork/Request/APIRequest.swift @@ -95,7 +95,7 @@ public enum APIRequest { /// Estimate required gas amount for transaction /// - Parameters: /// - TransactionParameters: parameters of planned transaction - /// - BlockNumber: block where it should be evalueated + /// - BlockNumber: block where it should be evaluated case estimateGas(CodableTransaction, BlockNumber) /// Send raw transaction @@ -114,7 +114,7 @@ public enum APIRequest { case getTransactionByHash(Hash) /// Get transaction receipt - /// - Paramters: + /// - Parameters: /// - Hash: transaction hash ID case getTransactionReceipt(Hash) @@ -134,7 +134,7 @@ public enum APIRequest { /// Mostly could be used for intreacting with a contracts, but also could be used for simple transaction sending /// - Parameters: /// - TransactionParameters: transaction to be sent into chain - /// - BlockNumber: block where it should be evalueated + /// - BlockNumber: block where it should be evaluated case call(CodableTransaction, BlockNumber) /// Get a transaction counts on a given block @@ -149,7 +149,7 @@ public enum APIRequest { /// Get a balance of a given address /// - Parameters: - /// - Address: address which balance would be recieved + /// - Address: address which balance would be received /// - BlockNumber: block to check case getBalance(Address, BlockNumber) @@ -190,7 +190,7 @@ public enum APIRequest { /// - BlockNumber: Highest block of the requested range. /// - [Double]: A monotonically increasing list of percentile values. /// For each block in the requested range, the transactions will be sorted in ascending order - /// by effective tip per gas and the coresponding effective tip for the percentile will be determined, accounting for gas consumed." + /// by effective tip per gas and the corresponding effective tip for the percentile will be determined, accounting for gas consumed." case feeHistory(BigUInt, BlockNumber, [Double]) // MARK: - Personal Ethereum API diff --git a/Sources/Web3Core/EthereumNetwork/RequestParameter/RequestParameter+Encodable.swift b/Sources/Web3Core/EthereumNetwork/RequestParameter/RequestParameter+Encodable.swift index 2a99dd1e0..a683d5fdc 100644 --- a/Sources/Web3Core/EthereumNetwork/RequestParameter/RequestParameter+Encodable.swift +++ b/Sources/Web3Core/EthereumNetwork/RequestParameter/RequestParameter+Encodable.swift @@ -9,7 +9,7 @@ import Foundation extension RequestParameter: Encodable { /** - This encoder encodes `RequestParameter` assotiated value ignoring self value + This encoder encodes `RequestParameter` associated value ignoring self value This is required to encode mixed types array, like @@ -48,7 +48,7 @@ extension RequestParameter: Encodable { case is CodableTransaction.Type: try enumContainer.encode(rawValue as! CodableTransaction) case is EventFilterParameters.Type: try enumContainer.encode(rawValue as! EventFilterParameters) - default: break /// can't be executed, coz possible `self.rawValue` types are strictly defined in it's inplementation.` + default: break /// can't be executed, coz possible `self.rawValue` types are strictly defined in it's implementation.` } // swiftlint:enable force_cast } diff --git a/Sources/Web3Core/EthereumNetwork/Utility/HexDecodableProtocols.swift b/Sources/Web3Core/EthereumNetwork/Utility/HexDecodableProtocols.swift index fede66d34..b4c57ca39 100644 --- a/Sources/Web3Core/EthereumNetwork/Utility/HexDecodableProtocols.swift +++ b/Sources/Web3Core/EthereumNetwork/Utility/HexDecodableProtocols.swift @@ -17,7 +17,7 @@ extension String: APIResultType { } /// /// You better not use it in any other part of a bit of code except `APIResponse` decoding. /// -/// This protocols intention is to work around that Ethereum API cases, when almost all numbers are comming as strings. +/// This protocols intention is to work around that Ethereum API cases, when almost all numbers are coming as strings. /// More than that their notation (e.g. 0x12d) are don't fit with the default Numeric decoders behaviours. /// So to work around that for generic cases we're going to force decode `APIResponse.result` field as `String` /// and then initiate it diff --git a/Sources/Web3Core/KeystoreManager/BIP44.swift b/Sources/Web3Core/KeystoreManager/BIP44.swift index d0d701e5d..9a80a396c 100644 --- a/Sources/Web3Core/KeystoreManager/BIP44.swift +++ b/Sources/Web3Core/KeystoreManager/BIP44.swift @@ -7,9 +7,9 @@ import Foundation public protocol BIP44 { /** - Derive an ``HDNode`` based on the provided path. The function will throw ``BIP44Error.warning`` if it was invoked with throwOnWarning equal to - `true` and the root key doesn't have a previous child with at least one transaction. If it is invoked with throwOnError equal to `false` the child node will be - derived directly using the derive function of ``HDNode``. This function needs to query the blockchain history when throwOnWarning is `true`, so it can throw + Derive an ``HDNode`` based on the provided path. The function will throw ``BIP44Error.warning`` if it was invoked with `throwOnWarning` equal to + `true` and the root key doesn't have a previous child with at least one transaction. If it is invoked with `throwOnWarning` equal to `false` the child node will be + derived directly using the derive function of ``HDNode``. This function needs to query the blockchain history when `throwOnWarning` is `true`, so it can throw network errors. - Parameter path: valid BIP44 path. - Parameter throwOnWarning: `true` to use @@ -41,7 +41,7 @@ public protocol TransactionChecker { - Throws: any error related to query the blockchain provider - Returns: `true` if the address has at least one transaction, `false` otherwise */ - func hasTransactions(address: String) async throws -> Bool + func hasTransactions(ethereumAddress: EthereumAddress) async throws -> Bool } extension HDNode: BIP44 { @@ -62,7 +62,7 @@ extension HDNode: BIP44 { if let searchPath = path.newPath(account: searchAccount, addressIndex: searchAddressIndex), let childNode = derive(path: searchPath, derivePrivateKey: true), let ethAddress = Utilities.publicToAddress(childNode.publicKey) { - hasTransactions = try await transactionChecker.hasTransactions(address: ethAddress.address) + hasTransactions = try await transactionChecker.hasTransactions(ethereumAddress: ethAddress) if hasTransactions { break } diff --git a/Sources/Web3Core/KeystoreManager/EtherscanTransactionChecker.swift b/Sources/Web3Core/KeystoreManager/EtherscanTransactionChecker.swift index 93318d151..1b0353285 100644 --- a/Sources/Web3Core/KeystoreManager/EtherscanTransactionChecker.swift +++ b/Sources/Web3Core/KeystoreManager/EtherscanTransactionChecker.swift @@ -8,6 +8,7 @@ import Foundation public struct EtherscanTransactionChecker: TransactionChecker { private let urlSession: URLSessionProxy private let apiKey: String + private let successRange = 200..<300 public init(urlSession: URLSession, apiKey: String) { self.urlSession = URLSessionProxyImplementation(urlSession: urlSession) @@ -19,13 +20,16 @@ public struct EtherscanTransactionChecker: TransactionChecker { self.apiKey = apiKey } - public func hasTransactions(address: String) async throws -> Bool { - let urlString = "https://api.etherscan.io/api?module=account&action=txlist&address=\(address)&startblock=0&page=1&offset=1&sort=asc&apikey=\(apiKey)" + public func hasTransactions(ethereumAddress: EthereumAddress) async throws -> Bool { + let urlString = "https://api.etherscan.io/api?module=account&action=txlist&address=\(ethereumAddress.address)&startblock=0&page=1&offset=1&sort=asc&apikey=\(apiKey)" guard let url = URL(string: urlString) else { throw EtherscanTransactionCheckerError.invalidUrl(url: urlString) } let request = URLRequest(url: url) let result = try await urlSession.data(for: request) + if let httpResponse = result.1 as? HTTPURLResponse, !successRange.contains(httpResponse.statusCode) { + throw EtherscanTransactionCheckerError.network(statusCode: httpResponse.statusCode) + } let response = try JSONDecoder().decode(Response.self, from: result.0) return !response.result.isEmpty } @@ -40,11 +44,14 @@ extension EtherscanTransactionChecker { public enum EtherscanTransactionCheckerError: LocalizedError, Equatable { case invalidUrl(url: String) + case network(statusCode: Int) public var errorDescription: String? { switch self { case let .invalidUrl(url): return "Couldn't create URL(string: \(url))" + case let .network(statusCode): + return "Network error, statusCode: \(statusCode)" } } } diff --git a/Sources/Web3Core/KeystoreManager/IBAN.swift b/Sources/Web3Core/KeystoreManager/IBAN.swift index 604f7dce7..164ff319f 100755 --- a/Sources/Web3Core/KeystoreManager/IBAN.swift +++ b/Sources/Web3Core/KeystoreManager/IBAN.swift @@ -64,9 +64,9 @@ public struct IBAN { internal static func decodeToInts(_ iban: String) -> String { let uppercasedIBAN = iban.replacingOccurrences(of: " ", with: "").uppercased() - let begining = String(uppercasedIBAN[0..<4]) + let beginning = String(uppercasedIBAN[0..<4]) let end = String(uppercasedIBAN[4...]) - let IBAN = end + begining + let IBAN = end + beginning var arrayOfInts = [Int]() for ch in IBAN { guard let dataPoint = String(ch).data(using: .ascii) else {return ""} diff --git a/Sources/Web3Core/Oracle/GasOracle.swift b/Sources/Web3Core/Oracle/GasOracle.swift index 2819f5adc..dee933f01 100644 --- a/Sources/Web3Core/Oracle/GasOracle.swift +++ b/Sources/Web3Core/Oracle/GasOracle.swift @@ -101,7 +101,7 @@ final public class Oracle { private func suggestTipValue() async throws -> [BigUInt] { var rearrengedArray: [[BigUInt]] = [] - /// reaarange `[[min, middle, max]]` to `[[min], [middle], [max]]` + /// rearrange `[[min, middle, max]]` to `[[min], [middle], [max]]` try await suggestGasValues().reward .forEach { percentiles in percentiles.enumerated().forEach { index, percentile in @@ -139,7 +139,7 @@ final public class Oracle { default: throw Web3Error.valueError(desc: "Unable to use '\(block)' policy to resolve block number to calculate gas fee suggestion.") } - /// checking if latest block number is greather than number of blocks to take in account + /// checking if latest block number is greater than number of blocks to take in account /// we're ignoring case when `latestBlockNumber` == `blockCount` since it's unlikely case /// which we could neglect guard latestBlockNumber > blockCount else { return [] } diff --git a/Sources/Web3Core/RLP/RLP.swift b/Sources/Web3Core/RLP/RLP.swift index c60a0afde..af5d8b29e 100755 --- a/Sources/Web3Core/RLP/RLP.swift +++ b/Sources/Web3Core/RLP/RLP.swift @@ -18,10 +18,9 @@ public struct RLP { static var length56 = BigUInt(UInt(56)) static var lengthMax = (BigUInt(UInt(1)) << 256) - internal static func encode(_ element: AnyObject) -> Data? { + internal static func encode(element: Any?) -> Data? { if let string = element as? String { return encode(string) - } else if let data = element as? Data { return encode(data) } else if let biguint = element as? BigUInt { @@ -112,14 +111,13 @@ public struct RLP { return encoded.bytes[0] } - // FIXME: Make encode generic to avoid casting it's argument to [AnyObject] internal static func encode(_ elements: [Any?]) -> Data? { var encodedData = Data() for e in elements { - if let encoded = encode(e as AnyObject) { + if let encoded = encode(element: e) { encodedData.append(encoded) } else { - guard let asArray = e as? [AnyObject] else {return nil} + guard let asArray = e as? [Any] else {return nil} guard let encoded = encode(asArray) else {return nil} encodedData.append(encoded) } diff --git a/Sources/Web3Core/Structure/Event+Protocol.swift b/Sources/Web3Core/Structure/Event+Protocol.swift index 87f361a08..aef5e3cd2 100755 --- a/Sources/Web3Core/Structure/Event+Protocol.swift +++ b/Sources/Web3Core/Structure/Event+Protocol.swift @@ -77,7 +77,7 @@ public enum Networks { static let allValues = [Mainnet, Ropsten, Kovan, Rinkeby] - public static func fromInt(_ networkID: UInt) -> Networks? { + public static func fromInt(_ networkID: UInt) -> Networks { switch networkID { case 1: return Networks.Mainnet diff --git a/Sources/Web3Core/Transaction/CodableTransaction.swift b/Sources/Web3Core/Transaction/CodableTransaction.swift index 19f5773fe..b478dc0f0 100644 --- a/Sources/Web3Core/Transaction/CodableTransaction.swift +++ b/Sources/Web3Core/Transaction/CodableTransaction.swift @@ -11,7 +11,7 @@ import BigInt /// While most fields in this struct are optional, they are not necessarily /// optional for the type of transaction they apply to. public struct CodableTransaction { - /// internal acccess only. The transaction envelope object itself that contains all the transaction data + /// internal access only. The transaction envelope object itself that contains all the transaction data /// and type specific implementation internal var envelope: AbstractEnvelope @@ -73,7 +73,7 @@ public struct CodableTransaction { set { return envelope.gasLimit = newValue } } - /// the price per gas unit for the tranaction (Legacy and EIP-2930 only) + /// the price per gas unit for the transaction (Legacy and EIP-2930 only) public var gasPrice: BigUInt? { get { return envelope.gasPrice } set { return envelope.gasPrice = newValue } @@ -147,7 +147,7 @@ public struct CodableTransaction { /// Signs the transaction /// - /// This method signs transaction iteself and not related to contract call data signing. + /// This method signs transaction itself and not related to contract call data signing. /// - Parameters: /// - privateKey: the private key to use for signing /// - useExtraEntropy: boolean whether to use extra entropy when signing (default false) @@ -265,7 +265,7 @@ extension CodableTransaction: Codable { } extension CodableTransaction: CustomStringConvertible { - /// required by CustomString convertable + /// required by CustomString convertible /// returns a string description for the transaction and its data public var description: String { var toReturn = "" @@ -290,7 +290,7 @@ extension CodableTransaction { /// - v: signature v parameter (default 1) - will get set properly once signed /// - r: signature r parameter (default 0) - will get set properly once signed /// - s: signature s parameter (default 0) - will get set properly once signed - /// - parameters: EthereumParameters object containing additional parametrs for the transaction like gas + /// - parameters: EthereumParameters object containing additional parameters for the transaction like gas public init(type: TransactionType? = nil, to: EthereumAddress, nonce: BigUInt = 0, chainID: BigUInt = 0, value: BigUInt = 0, data: Data = Data(), gasLimit: BigUInt = 0, maxFeePerGas: BigUInt? = nil, maxPriorityFeePerGas: BigUInt? = nil, gasPrice: BigUInt? = nil, diff --git a/Sources/Web3Core/Transaction/Envelope/AbstractEnvelope.swift b/Sources/Web3Core/Transaction/Envelope/AbstractEnvelope.swift index 5bb32c104..7986cddb1 100644 --- a/Sources/Web3Core/Transaction/Envelope/AbstractEnvelope.swift +++ b/Sources/Web3Core/Transaction/Envelope/AbstractEnvelope.swift @@ -60,8 +60,8 @@ public enum EncodeType { /// Protocol definition for all transaction envelope types /// All envelopes must conform to this protocol to work with `CodableTransaction` -/// each implememtation holds all the type specific data -/// and implments the type specific encoding/decoding +/// each implementation holds all the type specific data +/// and implements the type specific encoding/decoding protocol AbstractEnvelope: CustomStringConvertible { // possibly add Codable? /// The type of transaction this envelope represents @@ -115,7 +115,7 @@ protocol AbstractEnvelope: CustomStringConvertible { // possibly add Codable? // for Decodable support /// initializer for creating an `CodableTransaction` with the Decodable protocol /// will return an new `CodableTransaction` object on success - /// thows a `Web3.dataError` if an error occurs while trying to decode a value + /// throws a `Web3.dataError` if an error occurs while trying to decode a value /// returns nil if a required field is not found in the decoder stream init?(from decoder: Decoder) throws // Decodable Protocol diff --git a/Sources/Web3Core/Transaction/Envelope/EIP1559Envelope.swift b/Sources/Web3Core/Transaction/Envelope/EIP1559Envelope.swift index 052b931d9..4334a668c 100644 --- a/Sources/Web3Core/Transaction/Envelope/EIP1559Envelope.swift +++ b/Sources/Web3Core/Transaction/Envelope/EIP1559Envelope.swift @@ -45,7 +45,7 @@ public struct EIP1559Envelope: EIP2718Envelope, EIP2930Compatible { /// all exceed funds will be returned to the sender. /// /// If amount of this will be **lower** than sum of `Block.baseFeePerGas` and `maxPriorityFeePerGas` - /// miner will recieve amount calculated by the following equation: `maxFeePerGas - Block.baseFeePerGas` + /// miner will receive amount calculated by the following equation: `maxFeePerGas - Block.baseFeePerGas` /// where 'Block' is the block that the transaction will be included. public var maxFeePerGas: BigUInt? public var accessList: [AccessListEntry] // from EIP-2930 @@ -246,8 +246,7 @@ extension EIP1559Envelope { public func encode(for type: EncodeType = .transaction) -> Data? { let fields: [Any?] - let list = accessList.map { $0.encodeAsList() as AnyObject } - + let list = accessList.map { $0.encodeAsList() } switch type { case .transaction: fields = [chainID, nonce, maxPriorityFeePerGas, maxFeePerGas, gasLimit, to.addressData, value, data, list, v, r, s] diff --git a/Sources/Web3Core/Transaction/Envelope/EIP2930Envelope.swift b/Sources/Web3Core/Transaction/Envelope/EIP2930Envelope.swift index 93cfcbfb7..5034e4e76 100644 --- a/Sources/Web3Core/Transaction/Envelope/EIP2930Envelope.swift +++ b/Sources/Web3Core/Transaction/Envelope/EIP2930Envelope.swift @@ -207,7 +207,7 @@ extension EIP2930Envelope { public func encode(for type: EncodeType = .transaction) -> Data? { let fields: [Any?] - let list = accessList.map { $0.encodeAsList() as AnyObject } + let list = accessList.map { $0.encodeAsList() } switch type { case .transaction: @@ -310,7 +310,7 @@ public struct AccessListEntry: CustomStringConvertible, Codable { } } - public func encodeAsList() -> [AnyObject]? { + public func encodeAsList() -> [Any]? { var storage: [Data] = [] for key in storageKeys { @@ -318,7 +318,7 @@ public struct AccessListEntry: CustomStringConvertible, Codable { storage.append(keyData) } - return [address.address as AnyObject, storage as AnyObject] + return [address.address, storage] } // FIXME: THIS NOT WORKING!!! diff --git a/Sources/Web3Core/Transaction/Envelope/EnvelopeFactory.swift b/Sources/Web3Core/Transaction/Envelope/EnvelopeFactory.swift index 7fa3b0e9c..4e2f22749 100644 --- a/Sources/Web3Core/Transaction/Envelope/EnvelopeFactory.swift +++ b/Sources/Web3Core/Transaction/Envelope/EnvelopeFactory.swift @@ -74,7 +74,7 @@ public struct EnvelopeFactory { /// - v: signature v parameter (default 1) - will get set properly once signed /// - r: signature r parameter (default 0) - will get set properly once signed /// - s: signature s parameter (default 0) - will get set properly once signed - /// - options: TransactionParameters containing additional parametrs for the transaction like gas + /// - options: TransactionParameters containing additional parameters for the transaction like gas /// - Returns: a new envelope of type dictated by 'type' static func createEnvelope(type: TransactionType? = nil, to: EthereumAddress, nonce: BigUInt, chainID: BigUInt, value: BigUInt, data: Data, diff --git a/Sources/Web3Core/Transaction/Envelope/LegacyEnvelope.swift b/Sources/Web3Core/Transaction/Envelope/LegacyEnvelope.swift index 121ecb63b..a33df7c6e 100644 --- a/Sources/Web3Core/Transaction/Envelope/LegacyEnvelope.swift +++ b/Sources/Web3Core/Transaction/Envelope/LegacyEnvelope.swift @@ -35,7 +35,7 @@ public struct LegacyEnvelope: AbstractEnvelope { // legacy chainID Mechanism private var explicitChainID: BigUInt? // set directly or via options - // private var impliedChainID: BigUInt? // we calculate this once, or when explicitely asked to + // private var impliedChainID: BigUInt? // we calculate this once, or when explicitly asked to private var impliedChainID: BigUInt? { if r == 0 && s == 0 { return v } if v == 27 || v == 28 || v < 35 { return nil } @@ -54,7 +54,7 @@ public struct LegacyEnvelope: AbstractEnvelope { toReturn += "Data: " + self.data.toHexString().addHexPrefix().lowercased() + "\n" toReturn += "Resolved chainID: " + String(describing: self.chainID) + "\n" toReturn += "- Intrinsic chainID: " + String(describing: self.explicitChainID) + "\n" - toReturn += "- Infered chainID: " + String(describing: self.impliedChainID) + "\n" + toReturn += "- Inferred chainID: " + String(describing: self.impliedChainID) + "\n" toReturn += "v: " + String(self.v) + "\n" toReturn += "r: " + String(self.r) + "\n" toReturn += "s: " + String(self.s) + "\n" diff --git a/Sources/Web3Core/Transaction/EventfilterParameters.swift b/Sources/Web3Core/Transaction/EventfilterParameters.swift index bb959c9c3..7459f2dda 100755 --- a/Sources/Web3Core/Transaction/EventfilterParameters.swift +++ b/Sources/Web3Core/Transaction/EventfilterParameters.swift @@ -101,7 +101,7 @@ extension EventFilterParameters { var rawValue: String { switch self { case let .string(string): - // Assiciated value can contain only String or nil, both of them always encoded as a JSON could be represented as String again. + // Associated value can contain only String or nil, both of them always encoded as a JSON could be represented as String again. return String(data: try! JSONEncoder().encode(string), encoding: .utf8)! case let .strings(strings): return strings!.textRepresentation @@ -112,7 +112,7 @@ extension EventFilterParameters { extension EventFilterParameters: APIRequestParameterType { } -// - Why don't you develope some JSON composer to just send a server request, Yaroslav? +// - Why don't you develop some JSON composer to just send a server request, Yaroslav? // - Indeed, see no reason, why should i pass this. // Oh i wish to look deep in the Vitaliks eyes someday. extension Array where Element == EventFilterParameters.Topic? { diff --git a/Sources/Web3Core/Transaction/TransactionMetadata.swift b/Sources/Web3Core/Transaction/TransactionMetadata.swift index 28b6508d0..f70334290 100644 --- a/Sources/Web3Core/Transaction/TransactionMetadata.swift +++ b/Sources/Web3Core/Transaction/TransactionMetadata.swift @@ -44,7 +44,7 @@ public extension TransactionMetadata { } /// since metadata realistically can only come when a transaction is created from - /// JSON returned by a node, we only provide an intializer from JSON + /// JSON returned by a node, we only provide an initializer from JSON init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) diff --git a/Sources/Web3Core/Utility/Decodable+Extensions.swift b/Sources/Web3Core/Utility/Decodable+Extensions.swift index 0029df3cd..bd520b3fa 100644 --- a/Sources/Web3Core/Utility/Decodable+Extensions.swift +++ b/Sources/Web3Core/Utility/Decodable+Extensions.swift @@ -27,7 +27,7 @@ extension KeyedDecodingContainer { /// /// Currently this method supports only `Data.Type`, `BigUInt.Type`, `Date.Type`, `UInt.Type` /// - /// - Parameter type: Generic type `T` wich conforms to `DecodableFromHex` protocol + /// - Parameter type: Generic type `T` which conforms to `DecodableFromHex` protocol /// - Parameter key: The key that the decoded value is associated with. /// - Returns: A decoded value of type `T` /// - throws: `Web3Error.dataError` if value associated with key are unable to be initialized as `DecodableFromHex`. @@ -41,7 +41,7 @@ extension KeyedDecodingContainer { /// /// Currently this method supports only `Data.Type`, `BigUInt.Type`, `Date.Type`, `UInt.Type` /// - /// - Parameter type: Array of a generic type `T` wich conforms to `DecodableFromHex` protocol + /// - Parameter type: Array of a generic type `T` which conforms to `DecodableFromHex` protocol /// - Parameter key: The key that the decoded value is associated with. /// - Returns: A decoded value of type `[T]` /// - throws: `Web3Error.dataError` if value associated with key are unable to be initialized as `[[DecodableFromHex]]`. @@ -55,7 +55,7 @@ extension KeyedDecodingContainer { /// /// Currently this method supports only `Data.Type`, `BigUInt.Type`, `Date.Type`, `EthereumAddress`, `UInt.Type` /// - /// - Parameter type: Array of a generic type `T` wich conforms to `DecodableFromHex` protocol + /// - Parameter type: Array of a generic type `T` which conforms to `DecodableFromHex` protocol /// - Parameter key: The key that the decoded value is associated with. /// - Returns: A decoded value of type `[[T]]` /// - throws: `Web3Error.dataError` if value associated with key are unable to be initialized as `[[DecodableFromHex]]`. @@ -69,7 +69,7 @@ extension KeyedDecodingContainer { /// /// Currently this method supports only `Data.Type`, `BigUInt.Type`, `Date.Type`, `UInt.Type` /// - /// - Parameter type: Generic type `T` wich conforms to `DecodableFromHex` protocol + /// - Parameter type: Generic type `T` which conforms to `DecodableFromHex` protocol /// - Parameter key: The key that the decoded value is associated with. /// - Returns: A decoded value of type `T`, or nil if key is not present /// - throws: `Web3Error.dataError` if value associated with key are unable to be initialized as `DecodableFromHex`. @@ -84,7 +84,7 @@ extension UnkeyedDecodingContainer { /// /// Currently this method supports only `Data.Type`, `BigUInt.Type`, `Date.Type`, `EthereumAddress` /// - /// - Parameter type: Generic type `T` wich conforms to `DecodableFromHex` protocol + /// - Parameter type: Generic type `T` which conforms to `DecodableFromHex` protocol /// - Parameter key: The key that the decoded value is associated with. /// - Returns: A decoded value of type `BigUInt` /// - throws: `Web3Error.dataError` if value associated with key are unable to be initialized as `[DecodableFromHex]`. @@ -102,7 +102,7 @@ extension UnkeyedDecodingContainer { /// /// Currently this method supports only `Data.Type`, `BigUInt.Type`, `Date.Type`, `EthereumAddress` /// - /// - Parameter type: Generic type `T` wich conforms to `DecodableFromHex` protocol + /// - Parameter type: Generic type `T` which conforms to `DecodableFromHex` protocol /// - Parameter key: The key that the decoded value is associated with. /// - Returns: A decoded value of type `BigUInt` /// - throws: `Web3Error.dataError` if value associated with key are unable to be initialized as `[[DecodableFromHex]]`. diff --git a/Sources/Web3Core/Utility/String+Extension.swift b/Sources/Web3Core/Utility/String+Extension.swift index cf7537663..f63e077da 100755 --- a/Sources/Web3Core/Utility/String+Extension.swift +++ b/Sources/Web3Core/Utility/String+Extension.swift @@ -86,7 +86,7 @@ extension String { /// Strips leading zeroes from a HEX string. /// ONLY HEX string format is supported. - /// - Returns: string with stripped leading zeroes (and 0x prefix) or unchaged string. + /// - Returns: string with stripped leading zeroes (and 0x prefix) or unchanged string. func stripLeadingZeroes() -> String { let hex = addHexPrefix() guard let matcher = try? NSRegularExpression(pattern: "^(?0x)(?0+)(?[0-9a-fA-F]*)$", diff --git a/Sources/Web3Core/Utility/Utilities.swift b/Sources/Web3Core/Utility/Utilities.swift index 7b0557f6a..3d347e79a 100644 --- a/Sources/Web3Core/Utility/Utilities.swift +++ b/Sources/Web3Core/Utility/Utilities.swift @@ -10,34 +10,39 @@ import BigInt public struct Utilities { - /// Convert a public key to the corresponding EthereumAddress. Accepts public keys in compressed (33 bytes), non-compressed (65 bytes) - /// or raw concat(X, Y) (64 bytes) format. + /// Convert a public key to the corresponding ``EthereumAddress``. Accepts public keys in compressed (33 bytes), uncompressed (65 bytes) + /// or uncompressed without prefix (64 bytes) format. /// - /// Returns 20 bytes of address data. + /// - Parameter publicKey: compressed 33, non-compressed (65 bytes) or non-compressed without prefix (64 bytes) + /// - Returns: 20 bytes of address data. static func publicToAddressData(_ publicKey: Data) -> Data? { + var publicKey = publicKey if publicKey.count == 33 { - guard let decompressedKey = SECP256K1.combineSerializedPublicKeys(keys: [publicKey], outputCompressed: false) else {return nil} - return publicToAddressData(decompressedKey) - } - var stipped = publicKey - if stipped.count == 65 { - if stipped[0] != 4 { + guard (publicKey[0] == 2 || publicKey[0] == 3), + let decompressedKey = SECP256K1.combineSerializedPublicKeys(keys: [publicKey], outputCompressed: false) else { return nil } - stipped = stipped[1...64] + publicKey = decompressedKey } - if stipped.count != 64 { + + if publicKey.count == 65 { + guard publicKey[0] == 4 else { + return nil + } + publicKey = publicKey[1...64] + } else if publicKey.count != 64 { return nil } - let sha3 = stipped.sha3(.keccak256) + let sha3 = publicKey.sha3(.keccak256) let addressData = sha3[12...31] return addressData } - /// Convert a public key to the corresponding EthereumAddress. Accepts public keys in compressed (33 bytes), non-compressed (65 bytes) - /// or raw concat(X, Y) (64 bytes) format. + /// Convert a public key to the corresponding ``EthereumAddress``. Accepts public keys in compressed (33 bytes), uncompressed (65 bytes) + /// or uncompressed without prefix (64 bytes) format. /// - /// Returns the EthereumAddress object. + /// - Parameter publicKey: compressed 33, non-compressed (65 bytes) or non-compressed without prefix (64 bytes) + /// - Returns: `EthereumAddress` object. public static func publicToAddress(_ publicKey: Data) -> EthereumAddress? { guard let addressData = publicToAddressData(publicKey) else {return nil} let address = addressData.toHexString().addHexPrefix().lowercased() @@ -50,10 +55,11 @@ public struct Utilities { return publicKey } - /// Convert a public key to the corresponding EthereumAddress. Accepts public keys in compressed (33 bytes), non-compressed (65 bytes) - /// or raw concat(X, Y) (64 bytes) format. + /// Convert a public key to the corresponding ``EthereumAddress``. Accepts public keys in compressed (33 bytes), uncompressed (65 bytes) + /// or uncompressed without prefix (64 bytes) format. /// - /// Returns a 0x prefixed hex string. + /// - Parameter publicKey: compressed 33, non-compressed (65 bytes) or non-compressed without prefix (64 bytes) + /// - Returns: `0x` prefixed hex string. public static func publicToAddressString(_ publicKey: Data) -> String? { guard let addressData = Utilities.publicToAddressData(publicKey) else {return nil} let address = addressData.toHexString().addHexPrefix().lowercased() diff --git a/Sources/Web3Core/Web3Error/Web3Error.swift b/Sources/Web3Core/Web3Error/Web3Error.swift index bb21193dc..6a24b2456 100644 --- a/Sources/Web3Core/Web3Error/Web3Error.swift +++ b/Sources/Web3Core/Web3Error/Web3Error.swift @@ -27,7 +27,6 @@ public enum Web3Error: LocalizedError { public var errorDescription: String? { switch self { - case .transactionSerializationError: return "Transaction Serialization Error" case .connectionError: diff --git a/Sources/secp256k1/ecmult_impl.h b/Sources/secp256k1/ecmult_impl.h index feab1b741..61a5ffd23 100755 --- a/Sources/secp256k1/ecmult_impl.h +++ b/Sources/secp256k1/ecmult_impl.h @@ -339,7 +339,7 @@ static void secp256k1_ecmult_strauss_wnaf(const secp256k1_ecmult_context *ctx, c secp256k1_ge tmpa; secp256k1_fe Z; #ifdef USE_ENDOMORPHISM - /* Splitted G factors. */ + /* Split G factors. */ secp256k1_scalar ng_1, ng_128; int wnaf_ng_1[129]; int bits_ng_1 = 0; diff --git a/Sources/secp256k1/include/secp256k1.h b/Sources/secp256k1/include/secp256k1.h index ea2bc0155..c1fc13fac 100755 --- a/Sources/secp256k1/include/secp256k1.h +++ b/Sources/secp256k1/include/secp256k1.h @@ -399,7 +399,7 @@ SECP256K1_API int secp256k1_ecdsa_signature_serialize_compact( /** Verify an ECDSA signature. * * Returns: 1: correct signature - * 0: incorrect or unparseable signature + * 0: incorrect or unparsable signature * Args: ctx: a secp256k1 context object, initialized for verification. * In: sig: the signature being verified (cannot be NULL) * msg32: the 32-byte message hash being verified (cannot be NULL) diff --git a/Sources/web3swift/Browser/browser.js b/Sources/web3swift/Browser/browser.js index 6f7d8ea26..8cffd18b1 100644 --- a/Sources/web3swift/Browser/browser.js +++ b/Sources/web3swift/Browser/browser.js @@ -68348,4 +68348,3 @@ //# sourceURL=/Users/alexvlasov/Blockchain/web3swift/web3swiftJSProxy/wk.bridge.js },{}]},{},[1]); - \ No newline at end of file diff --git a/Sources/web3swift/Operations/ReadOperation.swift b/Sources/web3swift/Operations/ReadOperation.swift index 937ab2b14..50dc30ab4 100755 --- a/Sources/web3swift/Operations/ReadOperation.swift +++ b/Sources/web3swift/Operations/ReadOperation.swift @@ -36,13 +36,12 @@ public class ReadOperation { // TODO: Remove type erasing here, some broad wide protocol should be added instead public func callContractMethod() async throws -> [String: Any] { - // MARK: Read data from ABI flow // FIXME: This should be dropped, and after `execute()` call, just to decode raw data. let data: Data = try await self.web3.eth.callTransaction(transaction) if self.method == "fallback" { let resultHex = data.toHexString().addHexPrefix() - return ["result": resultHex as Any] + return ["result": resultHex] } guard let decodedData = self.contract.decodeReturnData(self.method, data: data) else { throw Web3Error.processingError(desc: "Can not decode returned parameters") diff --git a/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift b/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift index 3cc91263e..9c2d5ed01 100644 --- a/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift +++ b/Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift @@ -69,7 +69,7 @@ public class ERC1155: IERC1155 { } guard contract.contract.address != nil else {return} - guard let tokenIdPromise = try await contract.createReadOperation("id", parameters: [] as [AnyObject], extraData: Data())?.callContractMethod() else {return} + guard let tokenIdPromise = try await contract.createReadOperation("id")?.callContractMethod() else {return} guard let tokenId = tokenIdPromise["0"] as? BigUInt else {return} self._tokenId = tokenId @@ -79,46 +79,41 @@ public class ERC1155: IERC1155 { public func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, id: BigUInt, value: BigUInt, data: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, id, value, data] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, id, value, data])! return tx } public func safeBatchTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, ids: [BigUInt], values: [BigUInt], data: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) let tx = contract - .createWriteOperation("safeBatchTransferFrom", parameters: [originalOwner, to, ids, values, data] as [AnyObject])! + .createWriteOperation("safeBatchTransferFrom", parameters: [originalOwner, to, ids, values, data])! return tx } public func balanceOf(account: EthereumAddress, id: BigUInt) async throws -> BigUInt { let result = try await contract - .createReadOperation("balanceOf", parameters: [account, id] as [AnyObject], extraData: Data())! + .createReadOperation("balanceOf", parameters: [account, id])! .callContractMethod() - /* - let result = try await contract - .prepareToRead("balanceOf", parameters: [account, id] as [AnyObject], extraData: Data())! - .execute() - .decodeData() - - */ guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool, scope: Data) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setApprovalForAll", parameters: [user, approved, scope] as [AnyObject])! + let tx = contract.createWriteOperation("setApprovalForAll", parameters: [user, approved, scope])! return tx } public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress, scope: Data) async throws -> Bool { - let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user, scope] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user, scope])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } diff --git a/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift b/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift index 8b5a7b34d..80a4f796b 100644 --- a/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift +++ b/Sources/web3swift/Tokens/ERC1376/Web3+ERC1376.swift @@ -89,13 +89,15 @@ public class ERC1376: IERC1376, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -104,7 +106,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -114,7 +116,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } @@ -122,7 +124,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -132,8 +134,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } @@ -141,7 +142,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -151,8 +152,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } @@ -160,7 +160,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -170,13 +170,13 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -185,7 +185,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -198,8 +198,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let nValue = Utilities.parseToBigUInt(newValue, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, eValue, nValue] as [AnyObject])! + let tx = contract.createWriteOperation("approve", parameters: [spender, eValue, nValue])! return tx } @@ -207,7 +206,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -217,8 +216,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let amount = Utilities.parseToBigUInt(value, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("increaseAllowance", parameters: [spender, amount] as [AnyObject])! + let tx = contract.createWriteOperation("increaseAllowance", parameters: [spender, amount])! return tx } @@ -226,7 +224,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -236,20 +234,20 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let amount = Utilities.parseToBigUInt(value, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("decreaseAllowance", parameters: [spender, amount, strict] as [AnyObject])! + let tx = contract.createWriteOperation("decreaseAllowance", parameters: [spender, amount, strict])! return tx } func setERC20ApproveChecking(from: EthereumAddress, approveChecking: Bool) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setERC20ApproveChecking", parameters: [approveChecking] as [AnyObject])! + let tx = contract.createWriteOperation("setERC20ApproveChecking", parameters: [approveChecking])! return tx } func spendableAllowance(owner: EthereumAddress, spender: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("spendableAllowance", parameters: [owner, spender] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("spendableAllowance", parameters: [owner, spender])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -258,7 +256,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -268,7 +266,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(data, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [value] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [value])! return tx } @@ -276,7 +274,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -286,12 +284,13 @@ public class ERC1376: IERC1376, ERC20BaseProperties { guard let amount = Utilities.parseToBigUInt(value, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transferAndCall", parameters: [to, amount, data] as [AnyObject])! + let tx = contract.createWriteOperation("transferAndCall", parameters: [to, amount, data])! return tx } func nonceOf(owner: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("nonceOf", parameters: [owner] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("nonceOf", parameters: [owner])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -299,7 +298,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { func increaseNonce(from: EthereumAddress) throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("increaseNonce", parameters: [] as [AnyObject])! + let tx = contract.createWriteOperation("increaseNonce")! return tx } @@ -307,7 +306,7 @@ public class ERC1376: IERC1376, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -319,38 +318,38 @@ public class ERC1376: IERC1376, ERC20BaseProperties { } let modeValue = mode.rawValue - - let tx = contract.createWriteOperation("delegateTransferAndCall", parameters: [nonce, fee, gasAmount, to, amount, data, modeValue, v, r, s] as [AnyObject])! + let tx = contract.createWriteOperation("delegateTransferAndCall", parameters: [nonce, fee, gasAmount, to, amount, data, modeValue, v, r, s])! return tx } func directDebit(debtor: EthereumAddress, receiver: EthereumAddress) async throws -> DirectDebit { - let result = try await contract.createReadOperation("directDebit", parameters: [debtor, receiver] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("directDebit", parameters: [debtor, receiver])!.callContractMethod() + guard let res = result["0"] as? DirectDebit else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func setupDirectDebit(from: EthereumAddress, receiver: EthereumAddress, info: DirectDebitInfo) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setupDirectDebit", parameters: [receiver, info] as [AnyObject])! + let tx = contract.createWriteOperation("setupDirectDebit", parameters: [receiver, info])! return tx } func terminateDirectDebit(from: EthereumAddress, receiver: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("terminateDirectDebit", parameters: [receiver] as [AnyObject])! + let tx = contract.createWriteOperation("terminateDirectDebit", parameters: [receiver])! return tx } func withdrawDirectDebit(from: EthereumAddress, debtor: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("withdrawDirectDebit", parameters: [debtor] as [AnyObject])! + let tx = contract.createWriteOperation("withdrawDirectDebit", parameters: [debtor])! return tx } func withdrawDirectDebit(from: EthereumAddress, debtors: [EthereumAddress], strict: Bool) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("withdrawDirectDebit", parameters: [debtors, strict] as [AnyObject])! + let tx = contract.createWriteOperation("withdrawDirectDebit", parameters: [debtors, strict])! return tx } } diff --git a/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift b/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift index fbdbb48bb..df0874a93 100644 --- a/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift +++ b/Sources/web3swift/Tokens/ERC1400/Web3+ERC1400.swift @@ -10,49 +10,49 @@ import Web3Core // Security Token Standard protocol IERC1400: IERC20 { - + // Document Management func getDocument(name: Data) async throws -> (String, Data) func setDocument(from: EthereumAddress, name: Data, uri: String, documentHash: Data) async throws -> WriteOperation - + // Token Information func balanceOfByPartition(partition: Data, tokenHolder: EthereumAddress) async throws -> BigUInt func partitionsOf(tokenHolder: EthereumAddress) async throws -> [Data] - + // Transfers func transferWithData(from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func transferFromWithData(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation - + // Partition Token Transfers func transferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func operatorTransferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation - + // Controller Operation func isControllable() async throws -> Bool func controllerTransfer(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation func controllerRedeem(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation - + // Operator Management func authorizeOperator(from: EthereumAddress, operator user: EthereumAddress) async throws -> WriteOperation func revokeOperator(from: EthereumAddress, operator user: EthereumAddress) async throws -> WriteOperation func authorizeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) async throws -> WriteOperation func revokeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) async throws -> WriteOperation - + // Operator Information func isOperator(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool func isOperatorForPartition(partition: Data, operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool - + // Token Issuance func isIssuable() async throws -> Bool func issue(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func issueByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation - + // Token Redemption func redeem(from: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func redeemFrom(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func redeemByPartition(from: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> WriteOperation func operatorRedeemByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, operatorData: [UInt8]) async throws -> WriteOperation - + // Transfer Validity func canTransfer(to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) func canTransferFrom(originalOwner: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) @@ -70,9 +70,9 @@ public class ERC1400: IERC1400, ERC20BaseProperties { public var provider: Web3Provider public var address: EthereumAddress public var abi: String - + public let contract: Web3.Contract - + public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1400ABI, transaction: CodableTransaction = .emptyTransaction) { self.web3 = web3 self.provider = provider @@ -84,451 +84,465 @@ public class ERC1400: IERC1400, ERC20BaseProperties { contract = web3.contract(abi, at: address)! basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract) } - + public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } - + public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } - + public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } - + public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } - + // ERC1400 methods public func getDocument(name: Data) async throws -> (String, Data) { - let result = try await contract.createReadOperation("getDocument", parameters: [name] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getDocument", parameters: [name])!.callContractMethod() + guard let res = result["0"] as? (String, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func setDocument(from: EthereumAddress, name: Data, uri: String, documentHash: Data) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setDocument", parameters: [name, uri, documentHash] as [AnyObject])! + let tx = contract.createWriteOperation("setDocument", parameters: [name, uri, documentHash])! return tx } - + public func balanceOfByPartition(partition: Data, tokenHolder: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func partitionsOf(tokenHolder: EthereumAddress) async throws -> [Data] { - let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder])!.callContractMethod() + guard let res = result["0"] as? [Data] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transferWithData(from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferWithData", parameters: [to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("transferWithData", parameters: [to, value, data])! return tx } - + public func transferFromWithData(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFromWithData", parameters: [originalOwner, to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFromWithData", parameters: [originalOwner, to, value, data])! return tx } - + public func transferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferByPartition", parameters: [partition, to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("transferByPartition", parameters: [partition, to, value, data])! return tx } - + public func operatorTransferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("operatorTransferByPartition", parameters: [partition, originalOwner, to, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("operatorTransferByPartition", parameters: [partition, originalOwner, to, value, data, operatorData])! return tx } - + public func isControllable() async throws -> Bool { - let result = try await contract.createReadOperation("isControllable", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isControllable")!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func controllerTransfer(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("controllerTransfer", parameters: [originalOwner, to, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("controllerTransfer", parameters: [originalOwner, to, value, data, operatorData])! return tx } - + public func controllerRedeem(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("controllerRedeem", parameters: [tokenHolder, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("controllerRedeem", parameters: [tokenHolder, value, data, operatorData])! return tx } - + public func authorizeOperator(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("authorizeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("authorizeOperator", parameters: [user])! return tx } - + public func revokeOperator(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("revokeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("revokeOperator", parameters: [user])! return tx } - + public func authorizeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("authorizeOperatorByPartition", parameters: [partition, user] as [AnyObject])! + let tx = contract.createWriteOperation("authorizeOperatorByPartition", parameters: [partition, user])! return tx } - + public func revokeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("revokeOperatorByPartition", parameters: [partition, user] as [AnyObject])! + let tx = contract.createWriteOperation("revokeOperatorByPartition", parameters: [partition, user])! return tx } - + public func isOperator(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func isOperatorForPartition(partition: Data, operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func isIssuable() async throws -> Bool { - let result = try await contract.createReadOperation("isIssuable", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isIssuable")!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func issue(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("issue", parameters: [tokenHolder, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("issue", parameters: [tokenHolder, value, data])! return tx } - + public func issueByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("issueByPartition", parameters: [partition, tokenHolder, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("issueByPartition", parameters: [partition, tokenHolder, value, data])! return tx } - + public func redeem(from: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("redeem", parameters: [value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("redeem", parameters: [value, data])! return tx } - + public func redeemFrom(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("redeemFrom", parameters: [tokenHolder, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("redeemFrom", parameters: [tokenHolder, value, data])! return tx } - + public func redeemByPartition(from: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("redeemByPartition", parameters: [partition, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("redeemByPartition", parameters: [partition, value, data])! return tx } - + public func operatorRedeemByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("operatorRedeemByPartition", parameters: [partition, tokenHolder, value, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("operatorRedeemByPartition", parameters: [partition, tokenHolder, value, operatorData])! return tx } - + public func canTransfer(to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data] as [AnyObject], extraData: Data())!.callContractMethod() + + let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data])!.callContractMethod() + guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func canTransferFrom(originalOwner: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data] as [AnyObject], extraData: Data())!.callContractMethod() + + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data])!.callContractMethod() + guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func canTransferByPartition(originalOwner: EthereumAddress, to: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> ([UInt8], Data, Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data] as [AnyObject], extraData: Data())!.callContractMethod() + + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data])!.callContractMethod() + guard let res = result["0"] as? ([UInt8], Data, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -536,148 +550,159 @@ public class ERC1400: IERC1400, ERC20BaseProperties { extension ERC1400: IERC777 { public func canImplementInterfaceForAddress(interfaceHash: Data, addr: EthereumAddress) async throws -> Data { - let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.callContractMethod() + guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getInterfaceImplementer(addr: EthereumAddress, interfaceHash: Data) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.callContractMethod() + guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func setInterfaceImplementer(from: EthereumAddress, addr: EthereumAddress, interfaceHash: Data, implementer: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setInterfaceImplementer", parameters: [addr, interfaceHash, implementer] as [AnyObject])! + let tx = contract.createWriteOperation("setInterfaceImplementer", parameters: [addr, interfaceHash, implementer])! return tx } - + public func setManager(from: EthereumAddress, addr: EthereumAddress, newManager: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setManager", parameters: [addr, newManager] as [AnyObject])! + let tx = contract.createWriteOperation("setManager", parameters: [addr, newManager])! return tx } - + public func interfaceHash(interfaceName: String) async throws -> Data { - let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.callContractMethod() + guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func updateERC165Cache(from: EthereumAddress, contract: EthereumAddress, interfaceId: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = self.contract.createWriteOperation("updateERC165Cache", parameters: [contract, interfaceId] as [AnyObject])! + let tx = self.contract.createWriteOperation("updateERC165Cache", parameters: [contract, interfaceId])! return tx } - + public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getGranularity() async throws -> BigUInt { - let result = try await contract.createReadOperation("granularity", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("granularity")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getDefaultOperators() async throws -> [EthereumAddress] { - let result = try await contract.createReadOperation("defaultOperators", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("defaultOperators")!.callContractMethod() + guard let res = result["0"] as? [EthereumAddress] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func authorize(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("authorizeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("authorizeOperator", parameters: [user])! return tx } - + public func revoke(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("revokeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("revokeOperator", parameters: [user])! return tx } - + public func isOperatorFor(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func send(from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("send", parameters: [to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("send", parameters: [to, value, data])! return tx } - + public func operatorSend(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("operatorSend", parameters: [originalOwner, to, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("operatorSend", parameters: [originalOwner, to, value, data, operatorData])! return tx } - + public func burn(from: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("burn", parameters: [value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("burn", parameters: [value, data])! return tx } - + public func operatorBurn(from: EthereumAddress, amount: String, originalOwner: EthereumAddress, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("burn", parameters: [originalOwner, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("burn", parameters: [originalOwner, value, data, operatorData])! return tx } } @@ -685,11 +710,11 @@ extension ERC1400: IERC777 { // MARK: - Private extension ERC1400 { - + private func updateTransactionAndContract(from: EthereumAddress) { transaction.from = from transaction.to = address contract.transaction = transaction } - + } diff --git a/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift b/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift index 5cc788487..ed947f435 100644 --- a/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift +++ b/Sources/web3swift/Tokens/ERC1410/Web3+ERC1410.swift @@ -11,33 +11,33 @@ import Web3Core // Partially Fungible Token Standard protocol IERC1410: IERC20 { - + // Token Information func getBalance(account: EthereumAddress) async throws -> BigUInt func balanceOfByPartition(partition: Data, tokenHolder: EthereumAddress) async throws -> BigUInt func partitionsOf(tokenHolder: EthereumAddress) async throws -> [Data] func totalSupply() async throws -> BigUInt - + // Token Transfers func transferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func operatorTransferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation func canTransferByPartition(originalOwner: EthereumAddress, to: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> ([UInt8], Data, Data) - + // Operator Information func isOperator(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool func isOperatorForPartition(partition: Data, operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool - + // Operator Management func authorizeOperator(from: EthereumAddress, operator user: EthereumAddress) async throws -> WriteOperation func revokeOperator(from: EthereumAddress, operator user: EthereumAddress) async throws -> WriteOperation func authorizeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) async throws -> WriteOperation func revokeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) async throws -> WriteOperation - + // Issuance / Redemption func issueByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func redeemByPartition(from: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> WriteOperation func operatorRedeemByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, operatorData: [UInt8]) async throws -> WriteOperation - + } // FIXME: Rewrite this to CodableTransaction @@ -48,9 +48,9 @@ public class ERC1410: IERC1410, ERC20BaseProperties { public var provider: Web3Provider public var address: EthereumAddress public var abi: String - + public let contract: Web3.Contract - + public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1410ABI, transaction: CodableTransaction = .emptyTransaction) { self.web3 = web3 self.provider = provider @@ -62,407 +62,427 @@ public class ERC1410: IERC1410, ERC20BaseProperties { contract = web3.contract(abi, at: address)! basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract) } - + public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } - + public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } - + public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } - + public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } - + // ERC1410 methods public func balanceOfByPartition(partition: Data, tokenHolder: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOfByPartition", parameters: [partition, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func partitionsOf(tokenHolder: EthereumAddress) async throws -> [Data] { - let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("partitionsOf", parameters: [tokenHolder])!.callContractMethod() + guard let res = result["0"] as? [Data] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferByPartition", parameters: [partition, to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("transferByPartition", parameters: [partition, to, value, data])! return tx } - + public func operatorTransferByPartition(partition: Data, from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("operatorTransferByPartition", parameters: [partition, originalOwner, to, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("operatorTransferByPartition", parameters: [partition, originalOwner, to, value, data, operatorData])! return tx } - + public func canTransferByPartition(originalOwner: EthereumAddress, to: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> ([UInt8], Data, Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data] as [AnyObject], extraData: Data())!.callContractMethod() + + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, partition, value, data])!.callContractMethod() + guard let res = result["0"] as? ([UInt8], Data, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func isOperator(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isOperator", parameters: [user, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func isOperatorForPartition(partition: Data, operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorForPartition", parameters: [partition, user, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func authorizeOperator(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("authorizeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("authorizeOperator", parameters: [user])! return tx } - + public func revokeOperator(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("revokeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("revokeOperator", parameters: [user])! return tx } - + public func authorizeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("authorizeOperatorByPartition", parameters: [partition, user] as [AnyObject])! + let tx = contract.createWriteOperation("authorizeOperatorByPartition", parameters: [partition, user])! return tx } - + public func revokeOperatorByPartition(from: EthereumAddress, partition: Data, operator user: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("revokeOperatorByPartition", parameters: [partition, user] as [AnyObject])! + let tx = contract.createWriteOperation("revokeOperatorByPartition", parameters: [partition, user])! return tx } - + public func issueByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("issueByPartition", parameters: [partition, tokenHolder, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("issueByPartition", parameters: [partition, tokenHolder, value, data])! return tx } - + public func redeemByPartition(from: EthereumAddress, partition: Data, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("redeemByPartition", parameters: [partition, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("redeemByPartition", parameters: [partition, value, data])! return tx } - + public func operatorRedeemByPartition(from: EthereumAddress, partition: Data, tokenHolder: EthereumAddress, amount: String, operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("operatorRedeemByPartition", parameters: [partition, tokenHolder, value, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("operatorRedeemByPartition", parameters: [partition, tokenHolder, value, operatorData])! return tx } } extension ERC1410: IERC777 { public func canImplementInterfaceForAddress(interfaceHash: Data, addr: EthereumAddress) async throws -> Data { - let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.callContractMethod() + guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getInterfaceImplementer(addr: EthereumAddress, interfaceHash: Data) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.callContractMethod() + guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func setInterfaceImplementer(from: EthereumAddress, addr: EthereumAddress, interfaceHash: Data, implementer: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setInterfaceImplementer", parameters: [addr, interfaceHash, implementer] as [AnyObject])! + let tx = contract.createWriteOperation("setInterfaceImplementer", parameters: [addr, interfaceHash, implementer])! return tx } - + public func setManager(from: EthereumAddress, addr: EthereumAddress, newManager: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setManager", parameters: [addr, newManager] as [AnyObject])! + let tx = contract.createWriteOperation("setManager", parameters: [addr, newManager])! return tx } - + public func interfaceHash(interfaceName: String) async throws -> Data { - let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.callContractMethod() + guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func updateERC165Cache(from: EthereumAddress, contract: EthereumAddress, interfaceId: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = self.contract.createWriteOperation("updateERC165Cache", parameters: [contract, interfaceId] as [AnyObject])! + let tx = self.contract.createWriteOperation("updateERC165Cache", parameters: [contract, interfaceId])! return tx } - + public func supportsInterface(interfaceID: String) async throws -> Bool { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func authorize(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("authorizeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("authorizeOperator", parameters: [user])! return tx } - + public func revoke(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("revokeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("revokeOperator", parameters: [user])! return tx } - + public func isOperatorFor(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func send(from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("send", parameters: [to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("send", parameters: [to, value, data])! return tx } - + public func operatorSend(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("operatorSend", parameters: [originalOwner, to, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("operatorSend", parameters: [originalOwner, to, value, data, operatorData])! return tx } - + public func burn(from: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("burn", parameters: [value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("burn", parameters: [value, data])! return tx } - + public func operatorBurn(from: EthereumAddress, amount: String, originalOwner: EthereumAddress, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("burn", parameters: [originalOwner, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("burn", parameters: [originalOwner, value, data, operatorData])! return tx } - + public func getGranularity() async throws -> BigUInt { - let result = try await contract.createReadOperation("granularity", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("granularity")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getDefaultOperators() async throws -> [EthereumAddress] { - let result = try await contract.createReadOperation("defaultOperators", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("defaultOperators")!.callContractMethod() + guard let res = result["0"] as? [EthereumAddress] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -471,11 +491,11 @@ extension ERC1410: IERC777 { // MARK: - Private extension ERC1410 { - + private func updateTransactionAndContract(from: EthereumAddress) { transaction.from = from transaction.to = address contract.transaction = transaction } - + } diff --git a/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift b/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift index 0bba895bf..3e83074d8 100644 --- a/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift +++ b/Sources/web3swift/Tokens/ERC1594/Web3+ERC1594.swift @@ -11,23 +11,23 @@ import Web3Core // Core Security Token Standard protocol IERC1594: IERC20 { - + // Transfers func transferWithData(from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func transferFromWithData(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation - + // Token Issuance func isIssuable() async throws -> Bool func issue(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation - + // Token Redemption func redeem(from: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation func redeemFrom(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation - + // Transfer Validity func canTransfer(to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) func canTransferFrom(originalOwner: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) - + } // FIXME: Rewrite this to CodableTransaction @@ -38,9 +38,9 @@ public class ERC1594: IERC1594, ERC20BaseProperties { public var provider: Web3Provider public var address: EthereumAddress public var abi: String - + public let contract: Web3.Contract - + public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1594ABI, transaction: CodableTransaction = .emptyTransaction) { self.web3 = web3 self.provider = provider @@ -52,233 +52,240 @@ public class ERC1594: IERC1594, ERC20BaseProperties { contract = web3.contract(abi, at: address)! basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract) } - + public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } - + public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } - + public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } - + public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } - + // ERC1594 public func transferWithData(from: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferWithData", parameters: [to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("transferWithData", parameters: [to, value, data])! return tx } - + public func transferFromWithData(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFromWithData", parameters: [originalOwner, to, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFromWithData", parameters: [originalOwner, to, value, data])! return tx } - + public func isIssuable() async throws -> Bool { - let result = try await contract.createReadOperation("isIssuable", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isIssuable")!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func issue(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("issue", parameters: [tokenHolder, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("issue", parameters: [tokenHolder, value, data])! return tx } - + public func redeem(from: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("redeem", parameters: [value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("redeem", parameters: [value, data])! return tx } - + public func redeemFrom(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("redeemFrom", parameters: [tokenHolder, value, data] as [AnyObject])! + + let tx = contract.createWriteOperation("redeemFrom", parameters: [tokenHolder, value, data])! return tx } - + public func canTransfer(to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data] as [AnyObject], extraData: Data())!.callContractMethod() + + let result = try await contract.createReadOperation("canTransfer", parameters: [to, value, data])!.callContractMethod() + guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func canTransferFrom(originalOwner: EthereumAddress, to: EthereumAddress, amount: String, data: [UInt8]) async throws -> ([UInt8], Data) { // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data] as [AnyObject], extraData: Data())!.callContractMethod() + + let result = try await contract.createReadOperation("canTransfer", parameters: [originalOwner, to, value, data])!.callContractMethod() + guard let res = result["0"] as? ([UInt8], Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -287,11 +294,11 @@ public class ERC1594: IERC1594, ERC20BaseProperties { // MARK: - Private extension ERC1594 { - + private func updateTransactionAndContract(from: EthereumAddress) { transaction.from = from transaction.to = address contract.transaction = transaction } - + } diff --git a/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift b/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift index 79f8219a9..e7551fce1 100644 --- a/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift +++ b/Sources/web3swift/Tokens/ERC1633/Web3+ERC1633.swift @@ -12,10 +12,10 @@ import Web3Core // Re-Fungible Token Standard (RFT) // FIXME: Rewrite this to CodableTransaction protocol IERC1633: IERC20, IERC165 { - + func parentToken() async throws -> EthereumAddress func parentTokenId() async throws -> BigUInt - + } public class ERC1633: IERC1633, ERC20BaseProperties { @@ -25,9 +25,9 @@ public class ERC1633: IERC1633, ERC20BaseProperties { public var provider: Web3Provider public var address: EthereumAddress public var abi: String - + public let contract: Web3.Contract - + public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1633ABI, transaction: CodableTransaction = .emptyTransaction) { self.web3 = web3 self.provider = provider @@ -39,128 +39,135 @@ public class ERC1633: IERC1633, ERC20BaseProperties { contract = web3.contract(abi, at: address)! basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract) } - + public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } - + public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } - + public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } - + public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } - + func parentToken() async throws -> EthereumAddress { - let result = try await contract.createReadOperation("parentToken", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("parentToken")!.callContractMethod() + guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + func parentTokenId() async throws -> BigUInt { - let result = try await contract.createReadOperation("parentTokenId", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("parentTokenId")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + } // MARK: - Private extension ERC1633 { - + private func updateTransactionAndContract(from: EthereumAddress) { transaction.from = from transaction.to = address contract.transaction = transaction } - + } diff --git a/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift b/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift index 3885a1cf4..9e0c3fdec 100644 --- a/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift +++ b/Sources/web3swift/Tokens/ERC1643/Web3+ERC1643.swift @@ -11,13 +11,13 @@ import Web3Core // Document Management Standard protocol IERC1643: IERC20 { - + // Document Management func getDocument(name: Data) async throws -> (String, Data) func setDocument(from: EthereumAddress, name: Data, uri: String, documentHash: Data) async throws -> WriteOperation func removeDocument(from: EthereumAddress, name: Data) async throws -> WriteOperation func getAllDocuments() async throws -> [Data] - + } // FIXME: Rewrite this to CodableTransaction @@ -28,9 +28,9 @@ public class ERC1643: IERC1643, ERC20BaseProperties { public var provider: Web3Provider public var address: EthereumAddress public var abi: String - + public let contract: Web3.Contract - + public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1643ABI, transaction: CodableTransaction = .emptyTransaction) { self.web3 = web3 self.provider = provider @@ -42,121 +42,127 @@ public class ERC1643: IERC1643, ERC20BaseProperties { contract = web3.contract(abi, at: address)! basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract) } - + public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } - + public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } - + public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } - + public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } - + // ERC1643 methods public func getDocument(name: Data) async throws -> (String, Data) { - let result = try await contract.createReadOperation("getDocument", parameters: [name] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getDocument", parameters: [name])!.callContractMethod() + guard let res = result["0"] as? (String, Data) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func setDocument(from: EthereumAddress, name: Data, uri: String, documentHash: Data) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setDocument", parameters: [name, uri, documentHash] as [AnyObject])! + let tx = contract.createWriteOperation("setDocument", parameters: [name, uri, documentHash])! return tx } - + public func removeDocument(from: EthereumAddress, name: Data) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("removeDocument", parameters: [name] as [AnyObject])! + let tx = contract.createWriteOperation("removeDocument", parameters: [name])! return tx } - + public func getAllDocuments() async throws -> [Data] { - let result = try await contract.createReadOperation("getAllDocuments", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getAllDocuments")!.callContractMethod() + guard let res = result["0"] as? [Data] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -165,12 +171,12 @@ public class ERC1643: IERC1643, ERC20BaseProperties { // MARK: - Private extension ERC1643 { - + private func updateTransactionAndContract(from: EthereumAddress) { transaction.from = from transaction.to = address contract.transaction = transaction } - + } diff --git a/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift b/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift index b1921794d..1acaf69a1 100644 --- a/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift +++ b/Sources/web3swift/Tokens/ERC1644/Web3+ERC1644.swift @@ -11,12 +11,12 @@ import Web3Core // Controller Token Operation Standard protocol IERC1644: IERC20 { - + // Controller Operation func isControllable() async throws -> Bool func controllerTransfer(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation func controllerRedeem(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation - + } // FIXME: Rewrite this to CodableTransaction @@ -27,9 +27,9 @@ public class ERC1644: IERC1644, ERC20BaseProperties { public var provider: Web3Provider public var address: EthereumAddress public var abi: String - + public let contract: Web3.Contract - + public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.erc1644ABI, transaction: CodableTransaction = .emptyTransaction) { self.web3 = web3 self.provider = provider @@ -41,142 +41,147 @@ public class ERC1644: IERC1644, ERC20BaseProperties { contract = web3.contract(abi, at: address)! basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract) } - + public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } - + public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } - + public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } - + public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } - + // ERC1644 public func isControllable() async throws -> Bool { - let result = try await contract.createReadOperation("isControllable", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isControllable")!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func controllerTransfer(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("controllerTransfer", parameters: [originalOwner, to, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("controllerTransfer", parameters: [originalOwner, to, value, data, operatorData])! return tx } - + public func controllerRedeem(from: EthereumAddress, tokenHolder: EthereumAddress, amount: String, data: [UInt8], operatorData: [UInt8]) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("controllerRedeem", parameters: [tokenHolder, value, data, operatorData] as [AnyObject])! + + let tx = contract.createWriteOperation("controllerRedeem", parameters: [tokenHolder, value, data, operatorData])! return tx } } @@ -184,11 +189,11 @@ public class ERC1644: IERC1644, ERC20BaseProperties { // MARK: - Private extension ERC1644 { - + private func updateTransactionAndContract(from: EthereumAddress) { transaction.from = from transaction.to = address contract.transaction = transaction } - + } diff --git a/Sources/web3swift/Tokens/ERC20/ERC20BaseProperties.swift b/Sources/web3swift/Tokens/ERC20/ERC20BaseProperties.swift index e0d861fe7..806a038ee 100644 --- a/Sources/web3swift/Tokens/ERC20/ERC20BaseProperties.swift +++ b/Sources/web3swift/Tokens/ERC20/ERC20BaseProperties.swift @@ -7,7 +7,7 @@ import Foundation -/// Declares common properties of an [ERC-20](https://eips.ethereum.org/EIPS/eip-20) complient smart contract. +/// Declares common properties of an [ERC-20](https://eips.ethereum.org/EIPS/eip-20) compliant smart contract. /// Default implementation of access to these properties is declared in the extension of this protocol. public protocol ERC20BaseProperties: AnyObject { var basePropertiesProvider: ERC20BasePropertiesProvider { get } diff --git a/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift b/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift index 36ea8c26f..a3426f754 100644 --- a/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift +++ b/Sources/web3swift/Tokens/ERC20/Web3+ERC20.swift @@ -43,7 +43,7 @@ public class ERC20: IERC20, ERC20BaseProperties { public func getBalance(account: EthereumAddress) async throws -> BigUInt { let result = try await contract - .createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())! + .createReadOperation("balanceOf", parameters: [account])! .callContractMethod() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -51,7 +51,7 @@ public class ERC20: IERC20, ERC20BaseProperties { public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { let result = try await contract - .createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())! + .createReadOperation("allowance", parameters: [originalOwner, delegate])! .callContractMethod() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res @@ -64,7 +64,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract - .createReadOperation("decimals" )! + .createReadOperation("decimals")! .callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { @@ -75,8 +75,9 @@ public class ERC20: IERC20, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } + contract.transaction = transaction - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } @@ -87,7 +88,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract - .createReadOperation("decimals" )! + .createReadOperation("decimals")! .callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { @@ -98,8 +99,9 @@ public class ERC20: IERC20, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } + contract.transaction = transaction - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } @@ -110,7 +112,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract - .createReadOperation("decimals" )! + .createReadOperation("decimals")! .callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { @@ -121,8 +123,9 @@ public class ERC20: IERC20, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } + contract.transaction = transaction - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } @@ -133,7 +136,7 @@ public class ERC20: IERC20, ERC20BaseProperties { // get the decimals manually let callResult = try await contract - .createReadOperation("decimals" )! + .createReadOperation("decimals")! .callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { @@ -144,14 +147,15 @@ public class ERC20: IERC20, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } + contract.transaction = transaction - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } public func totalSupply() async throws -> BigUInt { let result = try await contract - .createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())! + .createReadOperation("totalSupply")! .callContractMethod() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res diff --git a/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift b/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift index a946b2deb..f7db95dd7 100644 --- a/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift +++ b/Sources/web3swift/Tokens/ERC721/Web3+ERC721.swift @@ -90,7 +90,7 @@ public class ERC721: IERC721 { } guard contract.contract.address != nil else {return} - async let tokenIdPromise = contract.createReadOperation("tokenId", parameters: [AnyObject](), extraData: Data())?.callContractMethod() + async let tokenIdPromise = contract.createReadOperation("tokenId")?.callContractMethod() guard let tokenIdResult = try await tokenIdPromise else {return} guard let tokenId = tokenIdResult["0"] as? BigUInt else {return} @@ -101,67 +101,67 @@ public class ERC721: IERC721 { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getOwner(tokenId: BigUInt) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId])!.callContractMethod() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getApproved(tokenId: BigUInt) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getApproved", parameters: [tokenId] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getApproved", parameters: [tokenId])!.callContractMethod() guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("transfer", parameters: [to, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [to, tokenId])! return tx } public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, tokenId])! return tx } public func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId])! return tx } public func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt, data: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, data] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, data])! return tx } public func approve(from: EthereumAddress, approved: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("approve", parameters: [approved, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("approve", parameters: [approved, tokenId])! return tx } public func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setApprovalForAll", parameters: [user, approved] as [AnyObject])! + let tx = contract.createWriteOperation("setApprovalForAll", parameters: [user, approved])! return tx } public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user])!.callContractMethod() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -185,19 +185,19 @@ extension ERC721 { extension ERC721: IERC721Enumerable { public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenByIndex(index: BigUInt) async throws -> BigUInt { - let result = try await contract.createReadOperation("tokenByIndex", parameters: [index] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokenByIndex", parameters: [index])!.callContractMethod() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenOfOwnerByIndex(owner: EthereumAddress, index: BigUInt) async throws -> BigUInt { - let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index])!.callContractMethod() guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -210,19 +210,19 @@ extension ERC721: IERC721Enumerable { extension ERC721: IERC721Metadata { public func name() async throws -> String { - let result = try await contract.createReadOperation("name", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("name")!.callContractMethod() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func symbol() async throws -> String { - let result = try await contract.createReadOperation("symbol", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("symbol")!.callContractMethod() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenURI(tokenId: BigUInt) async throws -> String { - let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId])!.callContractMethod() guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } diff --git a/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift b/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift index b7f839287..bce547e12 100644 --- a/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift +++ b/Sources/web3swift/Tokens/ERC721x/Web3+ERC721x.swift @@ -76,7 +76,7 @@ public class ERC721x: IERC721x { guard contract.contract.address != nil else {return} transaction.callOnBlock = .latest - guard let tokenIdPromise = try await contract.createReadOperation("tokenId", parameters: [] as [AnyObject], extraData: Data())?.callContractMethod() else {return} + guard let tokenIdPromise = try await contract.createReadOperation("tokenId")?.callContractMethod() else {return} guard let tokenId = tokenIdPromise["0"] as? BigUInt else {return} self._tokenId = tokenId @@ -86,165 +86,168 @@ public class ERC721x: IERC721x { public func getBalance(account: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getOwner(tokenId: BigUInt) async throws -> EthereumAddress { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("ownerOf", parameters: [tokenId])!.callContractMethod() + guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getApproved(tokenId: BigUInt) async throws -> EthereumAddress { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("getApproved", parameters: [tokenId] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getApproved", parameters: [tokenId])!.callContractMethod() + guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("transfer", parameters: [to, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [to, tokenId])! return tx } public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, tokenId])! return tx } public func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId])! return tx } public func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt, data: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, data] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, data])! return tx } public func approve(from: EthereumAddress, approved: EthereumAddress, tokenId: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("approve", parameters: [approved, tokenId] as [AnyObject])! + let tx = contract.createWriteOperation("approve", parameters: [approved, tokenId])! return tx } public func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setApprovalForAll", parameters: [user, approved] as [AnyObject])! + let tx = contract.createWriteOperation("setApprovalForAll", parameters: [user, approved])! return tx } public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress) async throws -> Bool { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isApprovedForAll", parameters: [owner, user])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func supportsInterface(interfaceID: String) async throws -> Bool { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func totalSupply() async throws -> BigUInt { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenByIndex(index: BigUInt) async throws -> BigUInt { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("tokenByIndex", parameters: [index] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokenByIndex", parameters: [index])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenOfOwnerByIndex(owner: EthereumAddress, index: BigUInt) async throws -> BigUInt { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokenOfOwnerByIndex", parameters: [owner, index])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func name() async throws -> String { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("name", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("name")!.callContractMethod() + guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func symbol() async throws -> String { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("symbol", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("symbol")!.callContractMethod() + guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func tokenURI(tokenId: BigUInt) async throws -> String { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokenURI", parameters: [tokenId])!.callContractMethod() + guard let res = result["0"] as? String else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func implementsERC721X() async throws -> Bool { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("implementsERC721X", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("implementsERC721X")!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func getBalance(account: EthereumAddress, tokenId: BigUInt) async throws -> BigUInt { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("balanceOf", parameters: [account, tokenId] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account, tokenId])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func tokensOwned(account: EthereumAddress) async throws -> ([BigUInt], [BigUInt]) { - transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("tokensOwned", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokensOwned", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? ([BigUInt], [BigUInt]) else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } func transfer(from: EthereumAddress, to: EthereumAddress, tokenId: BigUInt, quantity: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("transfer", parameters: [to, tokenId, quantity] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [to, tokenId, quantity])! return tx } func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt, quantity: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, tokenId, quantity] as [AnyObject])! + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, tokenId, quantity])! return tx } func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt, amount: BigUInt) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, amount] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, amount])! return tx } func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenId: BigUInt, amount: BigUInt, data: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, amount, data] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenId, amount, data])! return tx } func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, tokenIds: [BigUInt], amounts: [BigUInt], data: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenIds, amounts, data] as [AnyObject])! + let tx = contract.createWriteOperation("safeTransferFrom", parameters: [originalOwner, to, tokenIds, amounts, data])! return tx } } diff --git a/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift b/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift index 3af0acdef..f7360d913 100644 --- a/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift +++ b/Sources/web3swift/Tokens/ERC777/Web3+ERC777.swift @@ -57,25 +57,29 @@ public class ERC777: IERC777, ERC20BaseProperties { } public func getGranularity() async throws -> BigUInt { - let result = try await contract.createReadOperation("granularity", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("granularity")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getDefaultOperators() async throws -> [EthereumAddress] { - let result = try await contract.createReadOperation("defaultOperators", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("defaultOperators")!.callContractMethod() + guard let res = result["0"] as? [EthereumAddress] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -84,7 +88,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -94,7 +98,7 @@ public class ERC777: IERC777, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } @@ -102,7 +106,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -113,7 +117,7 @@ public class ERC777: IERC777, ERC20BaseProperties { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } @@ -121,7 +125,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -131,13 +135,13 @@ public class ERC777: IERC777, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -146,19 +150,20 @@ public class ERC777: IERC777, ERC20BaseProperties { public func authorize(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("authorizeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("authorizeOperator", parameters: [user])! return tx } public func revoke(from: EthereumAddress, operator user: EthereumAddress) throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("revokeOperator", parameters: [user] as [AnyObject])! + let tx = contract.createWriteOperation("revokeOperator", parameters: [user])! return tx } public func isOperatorFor(operator user: EthereumAddress, tokenHolder: EthereumAddress) async throws -> Bool { - let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("isOperatorFor", parameters: [user, tokenHolder])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -167,7 +172,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -177,7 +182,7 @@ public class ERC777: IERC777, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("send", parameters: [to, value, data] as [AnyObject])! + let tx = contract.createWriteOperation("send", parameters: [to, value, data])! return tx } @@ -185,7 +190,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -195,7 +200,7 @@ public class ERC777: IERC777, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("operatorSend", parameters: [originalOwner, to, value, data, operatorData] as [AnyObject])! + let tx = contract.createWriteOperation("operatorSend", parameters: [originalOwner, to, value, data, operatorData])! return tx } @@ -203,7 +208,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -213,7 +218,7 @@ public class ERC777: IERC777, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("burn", parameters: [value, data] as [AnyObject])! + let tx = contract.createWriteOperation("burn", parameters: [value, data])! return tx } @@ -221,7 +226,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -231,36 +236,39 @@ public class ERC777: IERC777, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("burn", parameters: [originalOwner, value, data, operatorData] as [AnyObject])! + let tx = contract.createWriteOperation("burn", parameters: [originalOwner, value, data, operatorData])! return tx } public func canImplementInterfaceForAddress(interfaceHash: Data, addr: EthereumAddress) async throws -> Data { - let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("canImplementInterfaceForAddress", parameters: [interfaceHash, addr])!.callContractMethod() + guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func getInterfaceImplementer(addr: EthereumAddress, interfaceHash: Data) async throws -> EthereumAddress { - let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("getInterfaceImplementer", parameters: [addr, interfaceHash])!.callContractMethod() + guard let res = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } public func setInterfaceImplementer(from: EthereumAddress, addr: EthereumAddress, interfaceHash: Data, implementer: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setInterfaceImplementer", parameters: [addr, interfaceHash, implementer] as [AnyObject])! + let tx = contract.createWriteOperation("setInterfaceImplementer", parameters: [addr, interfaceHash, implementer])! return tx } public func setManager(from: EthereumAddress, addr: EthereumAddress, newManager: EthereumAddress) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = contract.createWriteOperation("setManager", parameters: [addr, newManager] as [AnyObject])! + let tx = contract.createWriteOperation("setManager", parameters: [addr, newManager])! return tx } public func interfaceHash(interfaceName: String) async throws -> Data { - let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("interfaceHash", parameters: [interfaceName])!.callContractMethod() + guard let res = result["0"] as? Data else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -268,7 +276,7 @@ public class ERC777: IERC777, ERC20BaseProperties { // FIXME: might want to rename contract param here public func updateERC165Cache(from: EthereumAddress, contract: EthereumAddress, interfaceId: [UInt8]) throws -> WriteOperation { updateTransactionAndContract(from: from) - let tx = self.contract.createWriteOperation("updateERC165Cache", parameters: [contract, interfaceId] as [AnyObject])! + let tx = self.contract.createWriteOperation("updateERC165Cache", parameters: [contract, interfaceId])! return tx } @@ -276,7 +284,7 @@ public class ERC777: IERC777, ERC20BaseProperties { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -286,13 +294,13 @@ public class ERC777: IERC777, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } public func supportsInterface(interfaceID: String) async throws -> Bool { - let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("supportsInterface", parameters: [interfaceID])!.callContractMethod() + guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } diff --git a/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift b/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift index 65d472e54..1f462b08e 100644 --- a/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift +++ b/Sources/web3swift/Tokens/ERC888/Web3+ERC888.swift @@ -39,7 +39,8 @@ public class ERC888: IERC888, ERC20BaseProperties { } public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } @@ -50,7 +51,7 @@ public class ERC888: IERC888, ERC20BaseProperties { transaction.callOnBlock = .latest contract.transaction = transaction // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} @@ -59,7 +60,7 @@ public class ERC888: IERC888, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } diff --git a/Sources/web3swift/Tokens/ST20/Web3+ST20.swift b/Sources/web3swift/Tokens/ST20/Web3+ST20.swift index c6da4b9c6..52f603380 100644 --- a/Sources/web3swift/Tokens/ST20/Web3+ST20.swift +++ b/Sources/web3swift/Tokens/ST20/Web3+ST20.swift @@ -13,13 +13,13 @@ import Web3Core protocol IST20: IERC20 { // off-chain hash func tokenDetails() async throws -> [UInt32] - + // transfer, transferFrom must respect the result of verifyTransfer func verifyTransfer(from: EthereumAddress, originalOwner: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation - + // used to create tokens func mint(from: EthereumAddress, investor: EthereumAddress, amount: String) async throws -> WriteOperation - + // Burn function used to burn the securityToken func burn(from: EthereumAddress, amount: String) async throws -> WriteOperation } @@ -34,9 +34,9 @@ public class ST20: IST20, ERC20BaseProperties { public var provider: Web3Provider public var address: EthereumAddress public var abi: String - + public let contract: Web3.Contract - + public init(web3: Web3, provider: Web3Provider, address: EthereumAddress, abi: String = Web3.Utils.st20ABI, transaction: CodableTransaction = .emptyTransaction) { self.web3 = web3 self.provider = provider @@ -48,172 +48,178 @@ public class ST20: IST20, ERC20BaseProperties { contract = web3.contract(abi, at: address)! basePropertiesProvider = ERC20BasePropertiesProvider(contract: contract) } - + func tokenDetails() async throws -> [UInt32] { - let result = try await contract.createReadOperation("tokenDetails", parameters: [] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("tokenDetails")!.callContractMethod() + guard let res = result["0"] as? [UInt32] else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + func verifyTransfer(from: EthereumAddress, originalOwner: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("verifyTransfer", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("verifyTransfer", parameters: [originalOwner, to, value])! return tx } - + func mint(from: EthereumAddress, investor: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("mint", parameters: [investor, value] as [AnyObject])! + + let tx = contract.createWriteOperation("mint", parameters: [investor, value])! return tx } - + public func burn(from: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("burn", parameters: [value] as [AnyObject])! + + let tx = contract.createWriteOperation("burn", parameters: [value])! return tx } - + public func getBalance(account: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject], extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - let tx = contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transfer", parameters: [to, value])! return tx } - + public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! return tx } - + public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + + let tx = contract.createWriteOperation("setAllowance", parameters: [to, value])! return tx } - + public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { transaction.callOnBlock = .latest updateTransactionAndContract(from: from) // get the decimals manually - let callResult = try await contract.createReadOperation("decimals" )!.callContractMethod() + let callResult = try await contract.createReadOperation("decimals")!.callContractMethod() var decimals = BigUInt(0) guard let dec = callResult["0"], let decTyped = dec as? BigUInt else { throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")} decimals = decTyped - + let intDecimals = Int(decimals) guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - - let tx = contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + + let tx = contract.createWriteOperation("approve", parameters: [spender, value])! return tx } - + public func totalSupply() async throws -> BigUInt { - let result = try await contract.createReadOperation("totalSupply", parameters: [AnyObject](), extraData: Data())!.callContractMethod() + let result = try await contract.createReadOperation("totalSupply")!.callContractMethod() + guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")} return res } - + } // MARK: - Private extension ST20 { - + private func updateTransactionAndContract(from: EthereumAddress) { transaction.from = from transaction.to = address contract.transaction = transaction } - + } diff --git a/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift b/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift index 087e42768..b7c4a513e 100644 --- a/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift +++ b/Sources/web3swift/Tokens/ST20/Web3+SecurityToken.swift @@ -112,7 +112,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - return contract.createWriteOperation("verifyTransfer", parameters: [originalOwner, to, value] as [AnyObject])! + return contract.createWriteOperation("verifyTransfer", parameters: [originalOwner, to, value])! } func mint(from: EthereumAddress, investor: EthereumAddress, amount: String) async throws -> WriteOperation { @@ -131,7 +131,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - return contract.createWriteOperation("mint", parameters: [investor, value] as [AnyObject])! + return contract.createWriteOperation("mint", parameters: [investor, value])! } public func burn(from: EthereumAddress, amount: String) async throws -> WriteOperation { @@ -150,19 +150,19 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - return contract.createWriteOperation("burn", parameters: [value] as [AnyObject])! + return contract.createWriteOperation("burn", parameters: [value])! } public func getBalance(account: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOf", parameters: [account])!.callContractMethod() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func getAllowance(originalOwner: EthereumAddress, delegate: EthereumAddress) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("allowance", parameters: [originalOwner, delegate])!.callContractMethod() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } @@ -183,7 +183,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - return contract.createWriteOperation("transfer", parameters: [to, value] as [AnyObject])! + return contract.createWriteOperation("transfer", parameters: [to, value])! } public func transferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, amount: String) async throws -> WriteOperation { @@ -202,7 +202,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - return contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value] as [AnyObject])! + return contract.createWriteOperation("transferFrom", parameters: [originalOwner, to, value])! } public func setAllowance(from: EthereumAddress, to: EthereumAddress, newAmount: String) async throws -> WriteOperation { @@ -221,7 +221,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(newAmount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - return contract.createWriteOperation("setAllowance", parameters: [to, value] as [AnyObject])! + return contract.createWriteOperation("setAllowance", parameters: [to, value])! } public func approve(from: EthereumAddress, spender: EthereumAddress, amount: String) async throws -> WriteOperation { @@ -240,7 +240,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { guard let value = Utilities.parseToBigUInt(amount, decimals: intDecimals) else { throw Web3Error.inputError(desc: "Can not parse inputted amount") } - return contract.createWriteOperation("approve", parameters: [spender, value] as [AnyObject])! + return contract.createWriteOperation("approve", parameters: [spender, value])! } public func totalSupply() async throws -> BigUInt { @@ -254,16 +254,20 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.from = from transaction.to = self.address transaction.callOnBlock = .latest + contract.transaction = transaction - return contract.createWriteOperation("renounceOwnership", parameters: [AnyObject]() )! + return contract.createWriteOperation("renounceOwnership")! + } public func transferOwnership(from: EthereumAddress, newOwner: EthereumAddress) throws -> WriteOperation { transaction.from = from transaction.to = self.address transaction.callOnBlock = .latest + contract.transaction = transaction - return contract.createWriteOperation("transferOwnership", parameters: [newOwner] as [AnyObject])! + return contract.createWriteOperation("transferOwnership", parameters: [newOwner])! + } public func currentCheckpointId() async throws -> BigUInt { @@ -289,21 +293,21 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func investors(index: UInt) async throws -> [EthereumAddress] { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("investors", parameters: [index] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("investors", parameters: [index])!.callContractMethod() guard let res = result["0"] as? [EthereumAddress] else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func checkPermission(delegate: EthereumAddress, module: EthereumAddress, perm: [UInt32]) async throws -> Bool { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("checkPermission", parameters: [delegate, module, perm] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("checkPermission", parameters: [delegate, module, perm])!.callContractMethod() guard let res = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func getModule(moduleType: UInt8, moduleIndex: UInt8) async throws -> ([UInt32], EthereumAddress) { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("getModule", parameters: [moduleType, moduleIndex] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("getModule", parameters: [moduleType, moduleIndex])!.callContractMethod() guard let moduleList = result["0"] as? [UInt32] else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } guard let moduleAddress = result["1"] as? EthereumAddress else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return (moduleList, moduleAddress) @@ -311,7 +315,7 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func getModuleByName(moduleType: UInt8, name: [UInt32]) async throws -> ([UInt32], EthereumAddress) { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("getModuleByName", parameters: [moduleType, name] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("getModuleByName", parameters: [moduleType, name])!.callContractMethod() guard let moduleList = result["0"] as? [UInt32] else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } guard let moduleAddress = result["1"] as? EthereumAddress else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return (moduleList, moduleAddress) @@ -319,14 +323,14 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { public func totalSupplyAt(checkpointId: BigUInt) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("totalSupplyAt", parameters: [checkpointId] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("totalSupplyAt", parameters: [checkpointId])!.callContractMethod() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } public func balanceOfAt(investor: EthereumAddress, checkpointId: BigUInt) async throws -> BigUInt { transaction.callOnBlock = .latest - let result = try await contract.createReadOperation("balanceOfAt", parameters: [investor, checkpointId] as [AnyObject])!.callContractMethod() + let result = try await contract.createReadOperation("balanceOfAt", parameters: [investor, checkpointId])!.callContractMethod() guard let res = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node") } return res } @@ -335,8 +339,10 @@ public class SecurityToken: ISecurityToken, ERC20BaseProperties { transaction.from = from transaction.to = self.address transaction.callOnBlock = .latest + contract.transaction = transaction - return contract.createWriteOperation("createCheckpoint", parameters: [AnyObject]() )! + return contract.createWriteOperation("createCheckpoint")! + } public func getInvestorsLength() async throws -> BigUInt { diff --git a/Sources/web3swift/Utils/EIP/EIP67Code.swift b/Sources/web3swift/Utils/EIP/EIP67Code.swift index 49f4e887c..38e95b112 100755 --- a/Sources/web3swift/Utils/EIP/EIP67Code.swift +++ b/Sources/web3swift/Utils/EIP/EIP67Code.swift @@ -22,7 +22,7 @@ extension Web3 { } public struct Function { public var method: String - public var parameters: [(ABI.Element.ParameterType, AnyObject)] + public var parameters: [(ABI.Element.ParameterType, Any)] public func toString() -> String? { let encoding = method + "(" + parameters.map({ el -> String in diff --git a/Sources/web3swift/Utils/EIP/EIP681.swift b/Sources/web3swift/Utils/EIP/EIP681.swift index 62a05a509..264dc5d37 100755 --- a/Sources/web3swift/Utils/EIP/EIP681.swift +++ b/Sources/web3swift/Utils/EIP/EIP681.swift @@ -23,9 +23,9 @@ extension Web3 { public struct EIP681Code { public struct EIP681Parameter { public var type: ABI.Element.ParameterType - public var value: AnyObject + public var value: Any - public init(type: ABI.Element.ParameterType, value: AnyObject) { + public init(type: ABI.Element.ParameterType, value: Any) { self.type = type self.value = value } @@ -90,7 +90,7 @@ extension Web3 { public struct EIP681CodeEncoder { public static func encodeFunctionArgument(_ inputType: ABI.Element.ParameterType, - _ rawValue: AnyObject) -> String? { + _ rawValue: Any) -> String? { switch inputType { case .address: if let ethAddress = rawValue as? EthereumAddress { @@ -209,7 +209,7 @@ extension Web3 { } return nil case let .array(type, length): - if let array = rawValue as? [AnyObject] { + if let array = rawValue as? [Any] { let mappedArray = array.compactMap { object in encodeFunctionArgument(type, object) } @@ -234,20 +234,26 @@ extension Web3 { static var addressRegex = "^(pay-)?([0-9a-zA-Z.]+)(@[0-9]+)?\\/?(.*)?$" public static func parse(_ data: Data) async -> EIP681Code? { - guard let string = String(data: data, encoding: .utf8) else {return nil} + guard let string = String(data: data, encoding: .utf8) else { return nil } return await parse(string) } + // TODO: throws errors instead of returning `nil` + /// Attempts to parse given string as EIP681 code. + /// Note: that ENS addresses as parameters will be attempted to be resolved into Ethereum addresses. + /// Thus, make sure that given raw EIP681 code has chain ID set or default Ethereum Mainnet chan ID will be used instead. + /// - Parameter string: raw, encoded EIP681 code. + /// - Returns: parsed EIP681 code or `nil` is something has failed. public static func parse(_ string: String) async -> EIP681Code? { - guard string.hasPrefix("ethereum:") else {return nil} + guard string.hasPrefix("ethereum:") else { return nil } let striped = string.components(separatedBy: "ethereum:") - guard striped.count == 2 else {return nil} - guard let encoding = striped[1].removingPercentEncoding else {return nil} - // guard let url = URL.init(string: encoding) else {return nil} + guard striped.count == 2 else { return nil } + guard let encoding = striped[1].removingPercentEncoding else { return nil } + // guard let url = URL.init(string: encoding) else { return nil } let matcher = try! NSRegularExpression(pattern: addressRegex, options: NSRegularExpression.Options.dotMatchesLineSeparators) let match = matcher.matches(in: encoding, options: NSRegularExpression.MatchingOptions.anchored, range: encoding.fullNSRange) - guard match.count == 1 else {return nil} - guard match[0].numberOfRanges == 5 else {return nil} + guard match.count == 1 else { return nil } + guard match[0].numberOfRanges == 5 else { return nil } var addressString: String? var chainIDString: String? var tail: String? @@ -264,7 +270,7 @@ extension Web3 { if let tailRange = Range(match[0].range(at: 4), in: encoding) { tail = String(encoding[tailRange]) } - guard let address = addressString else {return nil} + guard let address = addressString else { return nil } let targetAddress = EIP681Code.TargetAddress(address) var code = EIP681Code(targetAddress) @@ -281,7 +287,7 @@ extension Web3 { } else { code.functionName = components.path } - guard let queryItems = components.queryItems else {return code} + guard let queryItems = components.queryItems else { return code } var inputNumber: Int = 0 var inputs = [ABI.Element.InOut]() for comp in queryItems { @@ -289,7 +295,7 @@ extension Web3 { guard let rawValue = comp.value, let functionArgument = await parseFunctionArgument(inputType, rawValue.trimmingCharacters(in: .whitespacesAndNewlines), - chainID: code.chainID ?? 0, + chainID: code.chainID, inputNumber: inputNumber) else { continue } @@ -299,10 +305,10 @@ extension Web3 { } else { switch comp.name { case "value": - guard let value = comp.value else {return nil} + guard let value = comp.value else { return nil } let splittedValue = value.split(separator: "e") if splittedValue.count <= 1 { - guard let val = BigUInt(value, radix: 10) else {return nil } + guard let val = BigUInt(value, radix: 10) else { return nil } code.amount = val } else if splittedValue.count == 2 { guard let power = Double(splittedValue[1]) else { return nil } @@ -321,16 +327,16 @@ extension Web3 { } else { return nil } case "gas": - guard let value = comp.value else {return nil} - guard let val = BigUInt(value, radix: 10) else {return nil} + guard let value = comp.value else { return nil } + guard let val = BigUInt(value, radix: 10) else { return nil } code.gasLimit = val case "gasLimit": - guard let value = comp.value else {return nil} - guard let val = BigUInt(value, radix: 10) else {return nil} + guard let value = comp.value else { return nil } + guard let val = BigUInt(value, radix: 10) else { return nil } code.gasLimit = val case "gasPrice": - guard let value = comp.value else {return nil} - guard let val = BigUInt(value, radix: 10) else {return nil} + guard let value = comp.value else { return nil } + guard let val = BigUInt(value, radix: 10) else { return nil } code.gasPrice = val default: continue @@ -348,60 +354,62 @@ extension Web3 { private static func parseFunctionArgument(_ inputType: ABI.Element.ParameterType, _ rawValue: String, - chainID: BigUInt, + chainID: BigUInt?, inputNumber: Int) async -> FunctionArgument? { - var nativeValue: AnyObject? + var nativeValue: Any? switch inputType { case .address: let val = EIP681Code.TargetAddress(rawValue) switch val { case .ethereumAddress(let ethereumAddress): - nativeValue = ethereumAddress as AnyObject + nativeValue = ethereumAddress case .ensAddress(let ens): + guard let chainID = chainID else { return nil } do { - let web = await Web3(provider: InfuraProvider(Networks.fromInt(UInt(chainID)) ?? Networks.Mainnet)!) + let web = await Web3(provider: InfuraProvider(.fromInt(UInt(chainID)))!) let ensModel = ENS(web3: web) try await ensModel?.setENSResolver(withDomain: ens) let address = try await ensModel?.getAddress(forNode: ens) - nativeValue = address as AnyObject + nativeValue = address } catch { + NSLog("Failed to resolve ENS address (parameter nr \(inputNumber)). Error: \(error.localizedDescription)") return nil } } case .uint(bits: _): if let val = BigUInt(rawValue, radix: 10) { - nativeValue = val as AnyObject + nativeValue = val } else if let val = BigUInt(rawValue.stripHexPrefix(), radix: 16) { - nativeValue = val as AnyObject + nativeValue = val } case .int(bits: _): if let val = BigInt(rawValue, radix: 10) { - nativeValue = val as AnyObject + nativeValue = val } else if let val = BigInt(rawValue.stripHexPrefix(), radix: 16) { - nativeValue = val as AnyObject + nativeValue = val } case .string: - nativeValue = rawValue as AnyObject + nativeValue = rawValue case .dynamicBytes: if let val = Data.fromHex(rawValue) { - nativeValue = val as AnyObject + nativeValue = val } else if let val = rawValue.data(using: .utf8) { - nativeValue = val as AnyObject + nativeValue = val } case .bytes(length: _): if let val = Data.fromHex(rawValue) { - nativeValue = val as AnyObject + nativeValue = val } else if let val = rawValue.data(using: .utf8) { - nativeValue = val as AnyObject + nativeValue = val } case .bool: switch rawValue { case "true", "True", "TRUE", "1": - nativeValue = true as AnyObject + nativeValue = true case "false", "False", "FALSE", "0": - nativeValue = false as AnyObject + nativeValue = false default: - nativeValue = true as AnyObject + nativeValue = true } case let .array(type, length): var rawValues: [String] = [] @@ -420,7 +428,7 @@ extension Web3 { rawValues = rawValue.split(separator: ",").map { String($0) } } - var nativeValueArray: [AnyObject] = [] + var nativeValueArray: [Any] = [] for value in rawValues { let intermidiateValue = await parseFunctionArgument(type, @@ -433,7 +441,7 @@ extension Web3 { nativeValueArray.append(intermidiateValue) } } - nativeValue = nativeValueArray as AnyObject + nativeValue = nativeValueArray guard nativeValueArray.count == rawValues.count && (length == 0 || UInt64(rawValues.count) == length) else { return nil } diff --git a/Sources/web3swift/Utils/EIP/EIP712.swift b/Sources/web3swift/Utils/EIP/EIP712.swift index 4cb913ffd..3d7606ebe 100644 --- a/Sources/web3swift/Utils/EIP/EIP712.swift +++ b/Sources/web3swift/Utils/EIP/EIP712.swift @@ -38,7 +38,6 @@ public extension EIP712Hashable { } func hash() throws -> Data { - typealias SolidityValue = (value: Any, type: ABI.Element.ParameterType) var parameters: [Data] = [typehash] for case let (_, field) in Mirror(reflecting: self).children { let result: Data @@ -48,14 +47,15 @@ public extension EIP712Hashable { case let data as EIP712.Bytes: result = data.sha3(.keccak256) case is EIP712.UInt8: - result = ABIEncoder.encodeSingleType(type: .uint(bits: 8), value: field as AnyObject)! + result = ABIEncoder.encodeSingleType(type: .uint(bits: 8), value: field)! case is EIP712.UInt256: - result = ABIEncoder.encodeSingleType(type: .uint(bits: 256), value: field as AnyObject)! + result = ABIEncoder.encodeSingleType(type: .uint(bits: 256), value: field)! case is EIP712.Address: - result = ABIEncoder.encodeSingleType(type: .address, value: field as AnyObject)! + result = ABIEncoder.encodeSingleType(type: .address, value: field)! case let hashable as EIP712Hashable: result = try hashable.hash() default: + /// Cast to `AnyObject` is required. Otherwise, `nil` value will fail this condition. if (field as AnyObject) is NSNull { continue } else { @@ -100,7 +100,7 @@ fileprivate extension EIP712Hashable { } func encodePrimaryType() -> String { - let parametrs: [String] = Mirror(reflecting: self).children.compactMap { key, value in + let parameters: [String] = Mirror(reflecting: self).children.compactMap { key, value in guard let key = key else { return nil } func checkIfValueIsNil(value: Any) -> Bool { @@ -127,7 +127,7 @@ fileprivate extension EIP712Hashable { } return typeName + " " + key } - return name + "(" + parametrs.joined(separator: ",") + ")" + return name + "(" + parameters.joined(separator: ",") + ")" } } diff --git a/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift b/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift index 2ee1f1706..a7082d731 100644 --- a/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift +++ b/Sources/web3swift/Utils/ENS/ENSBaseRegistrar.swift @@ -36,7 +36,7 @@ public extension ENS { public func addController(from: EthereumAddress, controllerAddress: EthereumAddress) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("addController", parameters: [controllerAddress as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("addController", parameters: [controllerAddress]) else { throw Web3Error.transactionSerializationError } return transaction } @@ -44,7 +44,7 @@ public extension ENS { public func removeController(from: EthereumAddress, controllerAddress: EthereumAddress) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("removeController", parameters: [controllerAddress as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("removeController", parameters: [controllerAddress]) else { throw Web3Error.transactionSerializationError } return transaction } @@ -52,29 +52,31 @@ public extension ENS { public func setResolver(from: EthereumAddress, resolverAddress: EthereumAddress) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("setResolver", parameters: [resolverAddress as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("setResolver", parameters: [resolverAddress]) else { throw Web3Error.transactionSerializationError } return transaction } public func getNameExpirity(name: BigUInt) async throws -> BigUInt { - guard let transaction = self.contract.createReadOperation("nameExpires", parameters: [name as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let expirity = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let transaction = self.contract.createReadOperation("nameExpires", parameters: [name]) else { throw Web3Error.transactionSerializationError } + + guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let expirity = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Can't get answer") } return expirity } @available(*, message: "This function should not be used to check if a name can be registered by a user. To check if a name can be registered by a user, check name availablility via the controller") public func isNameAvailable(name: BigUInt) async throws -> Bool { - guard let transaction = self.contract.createReadOperation("available", parameters: [name as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} - guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let available = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let transaction = self.contract.createReadOperation("available", parameters: [name]) else { throw Web3Error.transactionSerializationError } + + guard let result = try? await transaction.callContractMethod() else { throw Web3Error.processingError(desc: "Can't call transaction") } + guard let available = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Can't get answer") } return available } public func reclaim(from: EthereumAddress, record: BigUInt) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("reclaim", parameters: [record as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("reclaim", parameters: [record]) else { throw Web3Error.transactionSerializationError } return transaction } diff --git a/Sources/web3swift/Utils/ENS/ENSRegistry.swift b/Sources/web3swift/Utils/ENS/ENSRegistry.swift index 496bc038a..1e91001b0 100644 --- a/Sources/web3swift/Utils/ENS/ENSRegistry.swift +++ b/Sources/web3swift/Utils/ENS/ENSRegistry.swift @@ -47,7 +47,9 @@ public extension ENS { public func getOwner(node: String) async throws -> EthereumAddress { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.registryContract.createReadOperation("owner", parameters: [nameHash as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + + guard let transaction = self.registryContract.createReadOperation("owner", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let address = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "No address in result")} return address @@ -55,7 +57,9 @@ public extension ENS { public func getResolver(forDomain domain: String) async throws -> Resolver { guard let nameHash = NameHash.nameHash(domain) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.registryContract.createReadOperation("resolver", parameters: [nameHash as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + + guard let transaction = self.registryContract.createReadOperation("resolver", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let resolverAddress = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "No address in result")} return Resolver(web3: self.web3, resolverContractAddress: resolverAddress) @@ -63,7 +67,9 @@ public extension ENS { public func getTTL(node: String) async throws -> BigUInt { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.registryContract.createReadOperation("ttl", parameters: [nameHash as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + + guard let transaction = self.registryContract.createReadOperation("ttl", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let ans = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "No answer in result")} return ans @@ -76,7 +82,9 @@ public extension ENS { options.to = contractAddress } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.registryContract.createWriteOperation("setOwner", parameters: [nameHash, owner] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + + guard let transaction = self.registryContract.createWriteOperation("setOwner", parameters: [nameHash, owner]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } @@ -89,7 +97,9 @@ public extension ENS { } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} guard let labelHash = NameHash.nameHash(label) else {throw Web3Error.processingError(desc: "Failed to get label hash")} - guard let transaction = self.registryContract.createWriteOperation("setSubnodeOwner", parameters: [nameHash, labelHash, owner] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + + guard let transaction = self.registryContract.createWriteOperation("setSubnodeOwner", parameters: [nameHash, labelHash, owner]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } @@ -101,7 +111,9 @@ public extension ENS { options.to = contractAddress } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.registryContract.createWriteOperation("setResolver", parameters: [nameHash, resolver] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + + guard let transaction = self.registryContract.createWriteOperation("setResolver", parameters: [nameHash, resolver]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } @@ -113,7 +125,9 @@ public extension ENS { options.to = contractAddress } guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.registryContract.createWriteOperation("setTTL", parameters: [nameHash, ttl] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + + guard let transaction = self.registryContract.createWriteOperation("setTTL", parameters: [nameHash, ttl]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } diff --git a/Sources/web3swift/Utils/ENS/ENSResolver.swift b/Sources/web3swift/Utils/ENS/ENSResolver.swift index d1d8b064a..b7aedd589 100755 --- a/Sources/web3swift/Utils/ENS/ENSResolver.swift +++ b/Sources/web3swift/Utils/ENS/ENSResolver.swift @@ -75,7 +75,7 @@ public extension ENS { } public func supportsInterface(interfaceID: String) async throws -> Bool { - guard let transaction = self.resolverContract.createReadOperation("supportsInterface", parameters: [interfaceID as AnyObject]) else { + guard let transaction = self.resolverContract.createReadOperation("supportsInterface", parameters: [interfaceID]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else { @@ -89,7 +89,7 @@ public extension ENS { public func interfaceImplementer(forNode node: String, interfaceID: String) async throws -> EthereumAddress { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createReadOperation("interfaceImplementer", parameters: [nameHash, interfaceID] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createReadOperation("interfaceImplementer", parameters: [nameHash, interfaceID]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let address = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Can't get address")} return address @@ -97,7 +97,7 @@ public extension ENS { public func getAddress(forNode node: String) async throws -> EthereumAddress { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createReadOperation("addr", parameters: [nameHash as AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createReadOperation("addr", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let address = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Can't get address")} return address @@ -109,14 +109,14 @@ public extension ENS { var options = options ?? defaultTransaction options.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createWriteOperation("setAddr", parameters: [nameHash, address] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createWriteOperation("setAddr", parameters: [nameHash, address]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } public func getCanonicalName(forNode node: String) async throws -> String { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createReadOperation("name", parameters: [nameHash as AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createReadOperation("name", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let name = result["0"] as? String else {throw Web3Error.processingError(desc: "Can't get name")} return name @@ -128,14 +128,14 @@ public extension ENS { var options = options ?? defaultTransaction options.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createWriteOperation("setName", parameters: [nameHash, name] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createWriteOperation("setName", parameters: [nameHash, name]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } func getContentHash(forNode node: String) async throws -> Data { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createReadOperation("contenthash", parameters: [nameHash] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createReadOperation("contenthash", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let content = result["0"] as? Data else {throw Web3Error.processingError(desc: "Can't get content")} return content @@ -147,7 +147,7 @@ public extension ENS { var options = options ?? defaultTransaction options.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createWriteOperation("setContenthash", parameters: [nameHash, hash] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createWriteOperation("setContenthash", parameters: [nameHash, hash]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result @@ -155,7 +155,7 @@ public extension ENS { public func getContractABI(forNode node: String, contentType: ENS.Resolver.ContentType) async throws -> (BigUInt, Data) { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createReadOperation("ABI", parameters: [nameHash, contentType.rawValue] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createReadOperation("ABI", parameters: [nameHash, contentType.rawValue]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let encoding = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Can't get encoding")} guard let data = result["1"] as? Data else {throw Web3Error.processingError(desc: "Can't get data")} @@ -168,14 +168,14 @@ public extension ENS { var options = options ?? defaultTransaction options.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createWriteOperation("setABI", parameters: [nameHash, contentType.rawValue, data] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createWriteOperation("setABI", parameters: [nameHash, contentType.rawValue, data]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } public func getPublicKey(forNode node: String) async throws -> PublicKey { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createReadOperation("pubkey", parameters: [nameHash as AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createReadOperation("pubkey", parameters: [nameHash]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let x = result["x"] as? Data else {throw Web3Error.processingError(desc: "Can't get x")} guard let y = result["y"] as? Data else {throw Web3Error.processingError(desc: "Can't get y")} @@ -190,14 +190,14 @@ public extension ENS { options.to = self.resolverContractAddress let pubkeyWithoutPrefix = publicKey.getComponentsWithoutPrefix() guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createWriteOperation("setPubkey", parameters: [nameHash, pubkeyWithoutPrefix.x, pubkeyWithoutPrefix.y] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createWriteOperation("setPubkey", parameters: [nameHash, pubkeyWithoutPrefix.x, pubkeyWithoutPrefix.y]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } public func getTextData(forNode node: String, key: String) async throws -> String { guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createReadOperation("text", parameters: [nameHash, key] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createReadOperation("text", parameters: [nameHash, key]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} guard let text = result["0"] as? String else {throw Web3Error.processingError(desc: "Can't get text")} return text @@ -209,7 +209,7 @@ public extension ENS { var options = options ?? defaultTransaction options.to = self.resolverContractAddress guard let nameHash = NameHash.nameHash(node) else {throw Web3Error.processingError(desc: "Failed to get name hash")} - guard let transaction = self.resolverContract.createWriteOperation("setText", parameters: [nameHash, key, value] as [AnyObject]) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.resolverContract.createWriteOperation("setText", parameters: [nameHash, key, value]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.writeToChain(password: password) else {throw Web3Error.processingError(desc: "Can't send transaction")} return result } diff --git a/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift b/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift index aa7d41bc6..dfcff58f6 100644 --- a/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift +++ b/Sources/web3swift/Utils/ENS/ENSReverseRegistrar.swift @@ -32,35 +32,37 @@ public extension ENS { public func claimAddress(from: EthereumAddress, owner: EthereumAddress) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("claim", parameters: [owner as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("claim", parameters: [owner]) else { throw Web3Error.transactionSerializationError } return transaction } public func claimAddressWithResolver(from: EthereumAddress, owner: EthereumAddress, resolver: EthereumAddress) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("claimWithResolver", parameters: [owner, resolver] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("claimWithResolver", parameters: [owner, resolver]) else { throw Web3Error.transactionSerializationError } return transaction } public func setName(from: EthereumAddress, name: String) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("setName", parameters: [name] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("setName", parameters: [name]) else { throw Web3Error.transactionSerializationError } return transaction } public func getReverseRecordName(address: EthereumAddress) async throws -> Data { - guard let transaction = self.contract.createReadOperation("node", parameters: [address] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createReadOperation("node", parameters: [address]) else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let name = result["0"] as? Data else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let name = result["0"] as? Data else { throw Web3Error.processingError(desc: "Can't get answer") } return name } public func getDefaultResolver() async throws -> EthereumAddress { - guard let transaction = self.contract.createReadOperation("defaultResolver", parameters: [] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createReadOperation("defaultResolver") else { throw Web3Error.transactionSerializationError } + guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let address = result["0"] as? EthereumAddress else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let address = result["0"] as? EthereumAddress else { throw Web3Error.processingError(desc: "Can't get answer") } return address } } diff --git a/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift b/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift index 30b7a60d8..8802d5c33 100644 --- a/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift +++ b/Sources/web3swift/Utils/ENS/ETHRegistrarController.swift @@ -13,7 +13,7 @@ public extension ENS { class ETHRegistrarController { public let web3: Web3 public let address: EthereumAddress - + lazy var contract: Web3.Contract = { let contract = self.web3.contract(Web3.Utils.ethRegistrarControllerABI, at: self.address, abiVersion: 2) precondition(contract != nil) @@ -23,70 +23,70 @@ public extension ENS { lazy var defaultTransaction: CodableTransaction = { return CodableTransaction.emptyTransaction }() - + public init(web3: Web3, address: EthereumAddress) { self.web3 = web3 self.address = address } - + public func getRentPrice(name: String, duration: UInt) async throws -> BigUInt { - guard let transaction = self.contract.createReadOperation("rentPrice", parameters: [name, duration] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createReadOperation("rentPrice", parameters: [name, duration]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let price = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let price = result["0"] as? BigUInt else { throw Web3Error.processingError(desc: "Can't get answer") } return price } - + public func checkNameValidity(name: String) async throws -> Bool { - guard let transaction = self.contract.createReadOperation("valid", parameters: [name] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createReadOperation("valid", parameters: [name]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let valid = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let valid = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Can't get answer") } return valid } - + public func isNameAvailable(name: String) async throws -> Bool { - guard let transaction = self.contract.createReadOperation("available", parameters: [name as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createReadOperation("available", parameters: [name]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let available = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let available = result["0"] as? Bool else { throw Web3Error.processingError(desc: "Can't get answer") } return available } - + public func calculateCommitmentHash(name: String, owner: EthereumAddress, secret: String) async throws -> Data { - guard let transaction = self.contract.createReadOperation("makeCommitment", parameters: [name, owner.address, secret] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createReadOperation("makeCommitment", parameters: [name, owner.address, secret]) else { throw Web3Error.transactionSerializationError } guard let result = try? await transaction.callContractMethod() else {throw Web3Error.processingError(desc: "Can't call transaction")} - guard let hash = result["0"] as? Data else {throw Web3Error.processingError(desc: "Can't get answer")} + guard let hash = result["0"] as? Data else { throw Web3Error.processingError(desc: "Can't get answer") } return hash } - + public func sumbitCommitment(from: EthereumAddress, commitment: Data) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("commit", parameters: [commitment as AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("commit", parameters: [commitment]) else { throw Web3Error.transactionSerializationError } return transaction } - + public func registerName(from: EthereumAddress, name: String, owner: EthereumAddress, duration: UInt, secret: String, price: String) throws -> WriteOperation { guard let amount = Utilities.parseToBigUInt(price, units: .ether) else {throw Web3Error.inputError(desc: "Wrong price: no way for parsing to ether units")} defaultTransaction.value = amount defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("register", parameters: [name, owner.address, duration, secret] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("register", parameters: [name, owner.address, duration, secret]) else { throw Web3Error.transactionSerializationError } return transaction } - + public func extendNameRegistration(from: EthereumAddress, name: String, duration: UInt32, price: String) throws -> WriteOperation { guard let amount = Utilities.parseToBigUInt(price, units: .ether) else {throw Web3Error.inputError(desc: "Wrong price: no way for parsing to ether units")} defaultTransaction.value = amount defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("renew", parameters: [name, duration] as [AnyObject], extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("renew", parameters: [name, duration]) else { throw Web3Error.transactionSerializationError } return transaction } - + @available(*, message: "Available for only owner") public func withdraw(from: EthereumAddress) throws -> WriteOperation { defaultTransaction.from = from defaultTransaction.to = self.address - guard let transaction = self.contract.createWriteOperation("withdraw", parameters: [AnyObject](), extraData: Data()) else {throw Web3Error.transactionSerializationError} + guard let transaction = self.contract.createWriteOperation("withdraw") else { throw Web3Error.transactionSerializationError } return transaction } } diff --git a/Sources/web3swift/Utils/ENS/NameHash.swift b/Sources/web3swift/Utils/ENS/NameHash.swift index 723da72c4..c6e58412e 100755 --- a/Sources/web3swift/Utils/ENS/NameHash.swift +++ b/Sources/web3swift/Utils/ENS/NameHash.swift @@ -8,7 +8,7 @@ import CryptoSwift public struct NameHash { public static func normalizeDomainName(_ domain: String) -> String? { - // TODO use ICU4C library later for domain name normalization, althoug f**k it for now, it's few megabytes large piece + // TODO use ICU4C library later for domain name normalization, although f**k it for now, it's few megabytes large piece let normalized = domain.lowercased() return normalized } diff --git a/Sources/web3swift/Web3/Web3+Contract.swift b/Sources/web3swift/Web3/Web3+Contract.swift index ebb9bc41a..7ac561d66 100755 --- a/Sources/web3swift/Web3/Web3+Contract.swift +++ b/Sources/web3swift/Web3/Web3+Contract.swift @@ -53,7 +53,7 @@ extension Web3 { /// Returns a "Transaction intermediate" object. public func prepareDeploy(bytecode: Data, constructor: ABI.Element.Constructor? = nil, - parameters: [AnyObject]? = nil, + parameters: [Any]? = nil, extraData: Data? = nil) -> WriteOperation? { // MARK: Writing Data flow guard let data = self.contract.deploy(bytecode: bytecode, @@ -78,12 +78,12 @@ extension Web3 { // FIXME: Actually this is not rading contract or smth, this is about composing appropriate binary data to iterate with it later. // FIXME: Rewrite this to CodableTransaction /// Creates and object responsible for calling a particular function of the contract. If method name is not found in ABI - returns nil. - /// If extraData is supplied it is appended to encoded function parameters. Can be usefull if one wants to call + /// If extraData is supplied it is appended to encoded function parameters. Can be useful if one wants to call /// the function not listed in ABI. "Parameters" should be an array corresponding to the list of parameters of the function. /// Elements of "parameters" can be other arrays or instances of String, Data, BigInt, BigUInt, Int or EthereumAddress. /// /// Returns a "Transaction intermediate" object. - public func createReadOperation(_ method: String = "fallback", parameters: [AnyObject] = [AnyObject](), extraData: Data = Data()) -> ReadOperation? { + public func createReadOperation(_ method: String = "fallback", parameters: [Any] = [], extraData: Data = Data()) -> ReadOperation? { // MARK: - Encoding ABI Data flow guard let data = contract.method(method, parameters: parameters, extraData: extraData) else { return nil } @@ -99,12 +99,12 @@ extension Web3 { // FIXME: Rewrite this to CodableTransaction /// Creates and object responsible for calling a particular function of the contract. If method name is not found in ABI - returns nil. - /// If extraData is supplied it is appended to encoded function parameters. Can be usefull if one wants to call + /// If extraData is supplied it is appended to encoded function parameters. Can be useful if one wants to call /// the function not listed in ABI. "Parameters" should be an array corresponding to the list of parameters of the function. /// Elements of "parameters" can be other arrays or instances of String, Data, BigInt, BigUInt, Int or EthereumAddress. /// /// Returns a "Transaction intermediate" object. - public func createWriteOperation(_ method: String = "fallback", parameters: [AnyObject] = [AnyObject](), extraData: Data = Data()) -> WriteOperation? { + public func createWriteOperation(_ method: String = "fallback", parameters: [Any] = [], extraData: Data = Data()) -> WriteOperation? { guard let data = contract.method(method, parameters: parameters, extraData: extraData) else { return nil } transaction.data = data if let network = web3.provider.network { diff --git a/Sources/web3swift/Web3/Web3+Personal.swift b/Sources/web3swift/Web3/Web3+Personal.swift index 3949fcd7f..f83d328b8 100755 --- a/Sources/web3swift/Web3/Web3+Personal.swift +++ b/Sources/web3swift/Web3/Web3+Personal.swift @@ -34,7 +34,7 @@ extension Web3.Personal { - parameters: - account: EthereumAddress of the account to unlock - password: Password to use for the account - - seconds: Time inteval before automatic account lock by Ethereum node + - seconds: Time interval before automatic account lock by Ethereum node - returns: - Result object diff --git a/Sources/web3swift/Web3/Web3+Signing.swift b/Sources/web3swift/Web3/Web3+Signing.swift index 2e135c6c0..d1b57f270 100755 --- a/Sources/web3swift/Web3/Web3+Signing.swift +++ b/Sources/web3swift/Web3/Web3+Signing.swift @@ -18,7 +18,7 @@ public struct Web3Signer { defer { Data.zero(&privateKey) } try transaction.sign(privateKey: privateKey, useExtraEntropy: useExtraEntropy) } - + public static func signPersonalMessage(_ personalMessage: Data, keystore: T, account: EthereumAddress, @@ -32,14 +32,14 @@ public struct Web3Signer { useExtraEntropy: useExtraEntropy) return compressedSignature } - + public static func signEIP712(_ eip712Hashable: EIP712Hashable, keystore: BIP32Keystore, verifyingContract: EthereumAddress, account: EthereumAddress, password: String? = nil, chainId: BigUInt? = nil) throws -> Data { - + let domainSeparator: EIP712Hashable = EIP712Domain(chainId: chainId, verifyingContract: verifyingContract) let hash = try eip712encode(domainSeparator: domainSeparator, message: eip712Hashable) guard let signature = try Web3Signer.signPersonalMessage(hash, diff --git a/Sources/web3swift/Web3/Web3+Utils.swift b/Sources/web3swift/Web3/Web3+Utils.swift index e58005fd1..a5a3310b9 100755 --- a/Sources/web3swift/Web3/Web3+Utils.swift +++ b/Sources/web3swift/Web3/Web3+Utils.swift @@ -23,7 +23,7 @@ extension Web3.Utils { // /// and the nonce of this address // public static func calculateContractAddress(from: EthereumAddress, nonce: BigUInt) -> EthereumAddress? { // guard let normalizedAddress = from.addressData.setLengthLeft(32) else {return nil} - // guard let data = RLP.encode([normalizedAddress, nonce] as [AnyObject]) else {return nil} + // guard let data = RLP.encode([normalizedAddress, nonce]) else {return nil} // guard let contractAddressData = Utilities.sha3(data)?[12..<32] else {return nil} // guard let contractAddress = EthereumAddress(Data(contractAddressData)) else {return nil} // return contractAddress diff --git a/Sources/web3swift/Web3/Web3.swift b/Sources/web3swift/Web3/Web3.swift index 29c881130..e8b1a72df 100755 --- a/Sources/web3swift/Web3/Web3.swift +++ b/Sources/web3swift/Web3/Web3.swift @@ -6,14 +6,14 @@ import Foundation import Web3Core -/// An arbitary Web3 object. Is used only to construct provider bound fully functional object by either supplying provider URL +/// An arbitrary Web3 object. Is used only to construct provider bound fully functional object by either supplying provider URL /// or using pre-coded Infura nodes extension Web3 { /// Initialized provider-bound Web3 instance using a provider's URL. Under the hood it performs a synchronous call to get /// the Network ID for EIP155 purposes public static func new(_ providerURL: URL, network: Networks = .Mainnet) async throws -> Web3 { - // FIXME: Change this hardcoded value to dynamicly fethed from a Node + // FIXME: Change this hardcoded value to dynamically fethed from a Node guard let provider = await Web3HttpProvider(providerURL, network: network) else { throw Web3Error.inputError(desc: "Wrong provider - should be Web3HttpProvider with endpoint scheme http or https") } diff --git a/Tests/web3swiftTests/localTests/ABIEncoderTest.swift b/Tests/web3swiftTests/localTests/ABIEncoderTest.swift index 4b50fdecd..c6e6057f7 100644 --- a/Tests/web3swiftTests/localTests/ABIEncoderTest.swift +++ b/Tests/web3swiftTests/localTests/ABIEncoderTest.swift @@ -14,6 +14,16 @@ import BigInt class ABIEncoderTest: XCTestCase { + func testEncodeInt() { + XCTAssertEqual(ABIEncoder.encodeSingleType(type: .int(bits: 32), value: -10 as AnyObject)?.toHexString(), "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6") + XCTAssertEqual(ABIEncoder.encodeSingleType(type: .int(bits: 32), value: 10 as AnyObject)?.toHexString(), "000000000000000000000000000000000000000000000000000000000000000a") + } + + func testEncodeUInt() { + XCTAssertEqual(ABIEncoder.encodeSingleType(type: .uint(bits: 32), value: -10 as AnyObject), nil) + XCTAssertEqual(ABIEncoder.encodeSingleType(type: .uint(bits: 32), value: 10 as AnyObject)?.toHexString(), "000000000000000000000000000000000000000000000000000000000000000a") + } + func testSoliditySha3() throws { var hex = try ABIEncoder.soliditySha3(true).toHexString().addHexPrefix() assert(hex == "0x5fe7f977e71dba2ea1a68e21057beebb9be2ac30c6410aa38d4f3fbe41dcffd2") @@ -30,7 +40,7 @@ class ABIEncoderTest: XCTestCase { hex = try ABIEncoder.soliditySha3("Hello!%").toHexString().addHexPrefix() assert(hex == "0x661136a4267dba9ccdf6bfddb7c00e714de936674c4bdb065a531cf1cb15c7fc") - // This is not JS. '234' (with single or double qoutes) will be a String, not any kind of number. + // This is not JS. '234' (with single or double quotes) will be a String, not any kind of number. // From Web3JS docs:> web3.utils.soliditySha3('234'); // auto detects: uint256 hex = try ABIEncoder.soliditySha3(0xea).toHexString().addHexPrefix() @@ -103,7 +113,7 @@ class ABIEncoderTest: XCTestCase { } func testAbiEncodingEmptyValues() { - let zeroBytes = ABIEncoder.encode(types: [ABI.Element.InOut](), values: [AnyObject]())! + let zeroBytes = ABIEncoder.encode(types: [ABI.Element.InOut](), values: [Any]())! XCTAssert(zeroBytes.count == 0) let functionWithNoInput = ABI.Element.Function(name: "testFunction", @@ -117,69 +127,69 @@ class ABIEncoderTest: XCTestCase { } func testConvertToBigInt() { - XCTAssertEqual(ABIEncoder.convertToBigInt(BigInt(-29390909).serialize() as AnyObject), -29390909) - XCTAssertEqual(ABIEncoder.convertToBigInt(Data.fromHex("00FF")! as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigInt(BigInt(-29390909) as AnyObject), -29390909) - XCTAssertEqual(ABIEncoder.convertToBigInt(BigUInt(29390909) as AnyObject), 29390909) - XCTAssertEqual(ABIEncoder.convertToBigInt(UInt(123) as AnyObject), 123) - XCTAssertEqual(ABIEncoder.convertToBigInt(UInt8(254) as AnyObject), 254) - XCTAssertEqual(ABIEncoder.convertToBigInt(UInt16(9090) as AnyObject), 9090) - XCTAssertEqual(ABIEncoder.convertToBigInt(UInt32(747474) as AnyObject), 747474) - XCTAssertEqual(ABIEncoder.convertToBigInt(UInt64(45222) as AnyObject), 45222) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int(123) as AnyObject), 123) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int8(127) as AnyObject), 127) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int16(9090) as AnyObject), 9090) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int32(83888) as AnyObject), 83888) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int64(45222) as AnyObject), 45222) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int(-32213) as AnyObject), -32213) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int8(-10) as AnyObject), -10) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int16(-32000) as AnyObject), -32000) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int32(-50050500) as AnyObject), -50050500) - XCTAssertEqual(ABIEncoder.convertToBigInt(Int64(-2) as AnyObject), -2) - XCTAssertEqual(ABIEncoder.convertToBigInt("10" as AnyObject), 10) - XCTAssertEqual(ABIEncoder.convertToBigInt("-10" as AnyObject), -10) - XCTAssertEqual(ABIEncoder.convertToBigInt("FF" as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigInt("-FF" as AnyObject), -255) - XCTAssertEqual(ABIEncoder.convertToBigInt("0xFF" as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigInt(" 10 " as AnyObject), 10) - XCTAssertEqual(ABIEncoder.convertToBigInt(" -10 " as AnyObject), -10) - XCTAssertEqual(ABIEncoder.convertToBigInt(" FF " as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigInt(" -FF " as AnyObject), -255) - XCTAssertEqual(ABIEncoder.convertToBigInt(" 0xFF " as AnyObject), 255) + XCTAssertEqual(ABIEncoder.convertToBigInt(BigInt(-29390909).serialize()), -29390909) + XCTAssertEqual(ABIEncoder.convertToBigInt(Data.fromHex("00FF")!), 255) + XCTAssertEqual(ABIEncoder.convertToBigInt(BigInt(-29390909)), -29390909) + XCTAssertEqual(ABIEncoder.convertToBigInt(BigUInt(29390909)), 29390909) + XCTAssertEqual(ABIEncoder.convertToBigInt(UInt(123)), 123) + XCTAssertEqual(ABIEncoder.convertToBigInt(UInt8(254)), 254) + XCTAssertEqual(ABIEncoder.convertToBigInt(UInt16(9090)), 9090) + XCTAssertEqual(ABIEncoder.convertToBigInt(UInt32(747474)), 747474) + XCTAssertEqual(ABIEncoder.convertToBigInt(UInt64(45222)), 45222) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int(123)), 123) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int8(127)), 127) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int16(9090)), 9090) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int32(83888)), 83888) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int64(45222)), 45222) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int(-32213)), -32213) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int8(-10)), -10) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int16(-32000)), -32000) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int32(-50050500)), -50050500) + XCTAssertEqual(ABIEncoder.convertToBigInt(Int64(-2)), -2) + XCTAssertEqual(ABIEncoder.convertToBigInt("10"), 10) + XCTAssertEqual(ABIEncoder.convertToBigInt("-10"), -10) + XCTAssertEqual(ABIEncoder.convertToBigInt("FF"), 255) + XCTAssertEqual(ABIEncoder.convertToBigInt("-FF"), -255) + XCTAssertEqual(ABIEncoder.convertToBigInt("0xFF"), 255) + XCTAssertEqual(ABIEncoder.convertToBigInt(" 10 "), 10) + XCTAssertEqual(ABIEncoder.convertToBigInt(" -10 "), -10) + XCTAssertEqual(ABIEncoder.convertToBigInt(" FF "), 255) + XCTAssertEqual(ABIEncoder.convertToBigInt(" -FF "), -255) + XCTAssertEqual(ABIEncoder.convertToBigInt(" 0xFF "), 255) } func testConvertToBigUInt() { /// When negative value is serialized the first byte represents sign when decoding as a signed number. /// Unsigned numbers treat the first byte as just another byte of a number, not a sign. - XCTAssertEqual(ABIEncoder.convertToBigUInt(BigInt(-29390909).serialize() as AnyObject), 4324358205) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Data.fromHex("00FF")! as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigUInt(BigInt(-29390909) as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt(BigUInt(29390909) as AnyObject), 29390909) - XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt(123) as AnyObject), 123) - XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt8(254) as AnyObject), 254) - XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt16(9090) as AnyObject), 9090) - XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt32(747474) as AnyObject), 747474) - XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt64(45222) as AnyObject), 45222) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int(123) as AnyObject), 123) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int8(127) as AnyObject), 127) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int16(9090) as AnyObject), 9090) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int32(83888) as AnyObject), 83888) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int64(45222) as AnyObject), 45222) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int(-32213) as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int8(-10) as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int16(-32000) as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int32(-50050500) as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt(Int64(-2) as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt("10" as AnyObject), 10) - XCTAssertEqual(ABIEncoder.convertToBigUInt("-10" as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt("FF" as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigUInt("-FF" as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt("0xFF" as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigUInt(" 10 " as AnyObject), 10) - XCTAssertEqual(ABIEncoder.convertToBigUInt(" -10 " as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt(" FF " as AnyObject), 255) - XCTAssertEqual(ABIEncoder.convertToBigUInt(" -FF " as AnyObject), nil) - XCTAssertEqual(ABIEncoder.convertToBigUInt(" 0xFF " as AnyObject), 255) + XCTAssertEqual(ABIEncoder.convertToBigUInt(BigInt(-29390909).serialize()), 4324358205) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Data.fromHex("00FF")!), 255) + XCTAssertEqual(ABIEncoder.convertToBigUInt(BigInt(-29390909)), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt(BigUInt(29390909)), 29390909) + XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt(123)), 123) + XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt8(254)), 254) + XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt16(9090)), 9090) + XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt32(747474)), 747474) + XCTAssertEqual(ABIEncoder.convertToBigUInt(UInt64(45222)), 45222) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int(123)), 123) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int8(127)), 127) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int16(9090)), 9090) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int32(83888)), 83888) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int64(45222)), 45222) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int(-32213)), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int8(-10)), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int16(-32000)), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int32(-50050500)), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt(Int64(-2)), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt("10"), 10) + XCTAssertEqual(ABIEncoder.convertToBigUInt("-10"), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt("FF"), 255) + XCTAssertEqual(ABIEncoder.convertToBigUInt("-FF"), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt("0xFF"), 255) + XCTAssertEqual(ABIEncoder.convertToBigUInt(" 10 "), 10) + XCTAssertEqual(ABIEncoder.convertToBigUInt(" -10 "), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt(" FF "), 255) + XCTAssertEqual(ABIEncoder.convertToBigUInt(" -FF "), nil) + XCTAssertEqual(ABIEncoder.convertToBigUInt(" 0xFF "), 255) } /// When dynamic types (string, non-fixed size array, dynamic bytes) are encoded @@ -187,15 +197,15 @@ class ABIEncoderTest: XCTestCase { /// how much bytes should be skipped from the beginning of the resulting byte array to reach the /// value of the dynamic type. func testDynamicTypesDataOffset() { - var hexData = ABIEncoder.encode(types: [.string], values: ["test"] as [AnyObject])?.toHexString() + var hexData = ABIEncoder.encode(types: [.string], values: ["test"])?.toHexString() XCTAssertEqual(hexData?[0..<64], "0000000000000000000000000000000000000000000000000000000000000020") XCTAssertEqual(hexData, "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000047465737400000000000000000000000000000000000000000000000000000000") - hexData = ABIEncoder.encode(types: [.array(type: .uint(bits: 8), length: 0)], values: [[1,2,3,4]] as [AnyObject])?.toHexString() + hexData = ABIEncoder.encode(types: [.array(type: .uint(bits: 8), length: 0)], values: [[1,2,3,4]])?.toHexString() XCTAssertEqual(hexData?[0..<64], "0000000000000000000000000000000000000000000000000000000000000020") XCTAssertEqual(hexData, "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004") // This one shouldn't have data offset - hexData = ABIEncoder.encode(types: [.array(type: .uint(bits: 8), length: 4)], values: [[1,2,3,4]] as [AnyObject])?.toHexString() + hexData = ABIEncoder.encode(types: [.array(type: .uint(bits: 8), length: 4)], values: [[1,2,3,4]])?.toHexString() // First 32 bytes are the first value from the array XCTAssertEqual(hexData?[0..<64], "0000000000000000000000000000000000000000000000000000000000000001") XCTAssertEqual(hexData, "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004") @@ -204,7 +214,7 @@ class ABIEncoderTest: XCTestCase { .bool, .array(type: .uint(bits: 8), length: 0), .bytes(length: 2)] - let values: [AnyObject] = [10, false, [1,2,3,4], Data(count: 2)] as [AnyObject] + let values: [Any] = [10, false, [1,2,3,4], Data(count: 2)] hexData = ABIEncoder.encode(types: types, values: values)?.toHexString() XCTAssertEqual(hexData?[128..<192], "0000000000000000000000000000000000000000000000000000000000000080") XCTAssertEqual(hexData, "000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004") @@ -212,22 +222,22 @@ class ABIEncoderTest: XCTestCase { /// Test for the expected output when encoding dynamic types. func testAbiEncodingDynamicTypes() { - var encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("6761766f66796f726b")!] as [AnyObject])!.toHexString() + var encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("6761766f66796f726b")!])!.toHexString() XCTAssertEqual(encodedValue, "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096761766f66796f726b0000000000000000000000000000000000000000000000") - encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b")!] as [AnyObject])!.toHexString() + encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b")!])!.toHexString() XCTAssertEqual(encodedValue, "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020731a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b") - encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1")!] as [AnyObject])!.toHexString() + encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1")!])!.toHexString() XCTAssertEqual(encodedValue, "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000009ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff100") - encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("c3a40000c3a4")!] as [AnyObject])!.toHexString() + encodedValue = ABIEncoder.encode(types: [.dynamicBytes], values: [Data.fromHex("c3a40000c3a4")!])!.toHexString() XCTAssertEqual(encodedValue, "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006c3a40000c3a40000000000000000000000000000000000000000000000000000") - encodedValue = ABIEncoder.encode(types: [.string], values: ["gavofyork"] as [AnyObject])!.toHexString() + encodedValue = ABIEncoder.encode(types: [.string], values: ["gavofyork"])!.toHexString() XCTAssertEqual(encodedValue, "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096761766f66796f726b0000000000000000000000000000000000000000000000") - encodedValue = ABIEncoder.encode(types: [.string], values: ["Heeäööä👅D34ɝɣ24Єͽ-.,äü+#/"] as [AnyObject])!.toHexString() + encodedValue = ABIEncoder.encode(types: [.string], values: ["Heeäööä👅D34ɝɣ24Єͽ-.,äü+#/"])!.toHexString() XCTAssertEqual(encodedValue, "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000026486565c3a4c3b6c3b6c3a4f09f9185443334c99dc9a33234d084cdbd2d2e2cc3a4c3bc2b232f0000000000000000000000000000000000000000000000000000") } } diff --git a/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift b/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift index f9bc88ef2..7f174b784 100755 --- a/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift +++ b/Tests/web3swiftTests/localTests/AdvancedABIv2Tests.swift @@ -55,7 +55,7 @@ class AdvancedABIv2Tests: LocalTestCase { let allAddresses = try await web3.eth.ownedAccounts() var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - let parameters = [] as [AnyObject] + let parameters: [Any] = [] // MARK: Writing Data flow let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! deployTx.transaction.from = allAddresses[0] @@ -90,7 +90,7 @@ class AdvancedABIv2Tests: LocalTestCase { let allAddresses = try await web3.eth.ownedAccounts() var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - let parameters = [] as [AnyObject] + let parameters: [Any] = [] // MARK: Writing Data flow let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! deployTx.transaction.from = allAddresses[0] @@ -124,7 +124,7 @@ class AdvancedABIv2Tests: LocalTestCase { let allAddresses = try await web3.eth.ownedAccounts() var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - let parameters = [] as [AnyObject] + let parameters: [Any] = [] // MARK: Writing Data flow let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! deployTx.transaction.from = allAddresses[0] @@ -159,7 +159,7 @@ class AdvancedABIv2Tests: LocalTestCase { let allAddresses = try await web3.eth.ownedAccounts() var contract = web3.contract(abiString, at: nil, abiVersion: 2)! - let parameters = [] as [AnyObject] + let parameters: [Any] = [] // MARK: Writing Data flow let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! deployTx.transaction.from = allAddresses[0] diff --git a/Tests/web3swiftTests/localTests/BIP44Tests.swift b/Tests/web3swiftTests/localTests/BIP44Tests.swift index 400a2f6bb..95aa115e9 100644 --- a/Tests/web3swiftTests/localTests/BIP44Tests.swift +++ b/Tests/web3swiftTests/localTests/BIP44Tests.swift @@ -192,8 +192,8 @@ private final class MockTransactionChecker: TransactionChecker { var addresses: [String] = .init() var results: [Bool] = .init() - func hasTransactions(address: String) async throws -> Bool { - addresses.append(address) + func hasTransactions(ethereumAddress: EthereumAddress) async throws -> Bool { + addresses.append(ethereumAddress.address) return results.removeFirst() } } diff --git a/Tests/web3swiftTests/localTests/BasicLocalNodeTests.swift b/Tests/web3swiftTests/localTests/BasicLocalNodeTests.swift index e71641ee3..4ad43fc53 100755 --- a/Tests/web3swiftTests/localTests/BasicLocalNodeTests.swift +++ b/Tests/web3swiftTests/localTests/BasicLocalNodeTests.swift @@ -2,7 +2,7 @@ // Created by Alex Vlasov. // Copyright © 2018 Alex Vlasov. All rights reserved. // -// TODO: Replace `XCTAssert` with more explicite `XCTAssertEqual`, where Applicable +// TODO: Replace `XCTAssert` with more explicit `XCTAssertEqual`, where Applicable import XCTest import CryptoSwift import BigInt @@ -21,7 +21,7 @@ class BasicLocalNodeTests: LocalTestCase { let contract = web3.contract(abiString, at: nil, abiVersion: 2)! - let parameters = [] as [AnyObject] + let parameters: [Any] = [] let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! deployTx.transaction.from = allAddresses[0] let policies = Policies(gasLimitPolicy: .manual(3000000)) @@ -48,7 +48,7 @@ class BasicLocalNodeTests: LocalTestCase { let sendToAddress = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901")! let contract = web3.contract(Web3.Utils.coldWalletABI, at: sendToAddress, abiVersion: 2)! - let parameters = [] as [AnyObject] + let parameters: [Any] = [] let sendTx = contract.createWriteOperation("fallback", parameters: parameters)! let valueToSend = try XCTUnwrap(Utilities.parseToBigUInt("1.0", units: .ether)) diff --git a/Tests/web3swiftTests/localTests/EIP1559BlockTests.swift b/Tests/web3swiftTests/localTests/EIP1559BlockTests.swift index e41c55e3f..d9c0aeaee 100644 --- a/Tests/web3swiftTests/localTests/EIP1559BlockTests.swift +++ b/Tests/web3swiftTests/localTests/EIP1559BlockTests.swift @@ -18,7 +18,7 @@ class EIP1559BlockTests: LocalTestCase { logsBloom: EthereumBloomFilter(Data(from: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")!), // "logsBloom": transactionsRoot: Data(from: "0x3a1b03875115b79539e5bd33fb00d8f7b7cd61929d5a3c574f507b8acf415bee")!, // "transactionsRoot": stateRoot: Data(from: "0xf1133199d44695dfa8fd1bcfe424d82854b5cebef75bddd7e40ea94cda515bcb")!, // "stateRoot": - miner: EthereumAddress( Data(from: "0x8888f1f195afa192cfee860698584c030f4c9db1")!)!, // "miner": + miner: EthereumAddress(Data(from: "0x8888f1f195afa192cfee860698584c030f4c9db1")!)!, // "miner": difficulty: BigUInt(21345678965432), // "difficulty": totalDifficulty: BigUInt(324567845321), // "totalDifficulty": size: BigUInt(616), // "size": @@ -57,8 +57,8 @@ class EIP1559BlockTests: LocalTestCase { (40_000_000, 12_965_000, 39_960_938, false) // Lower limit -1 ] - headerArray.forEach { (touple: (parentGasLimit: BigUInt, parentNumber: BigUInt, currentGasLimit: BigUInt, is1559: Bool)) in - let parent = Block(number: touple.parentNumber, + headerArray.forEach { (tuple: (parentGasLimit: BigUInt, parentNumber: BigUInt, currentGasLimit: BigUInt, is1559: Bool)) in + let parent = Block(number: tuple.parentNumber, hash: uselessBlockPart.hash, parentHash: uselessBlockPart.parentHash, nonce: uselessBlockPart.nonce, @@ -72,14 +72,14 @@ class EIP1559BlockTests: LocalTestCase { totalDifficulty: uselessBlockPart.totalDifficulty, extraData: uselessBlockPart.extraData, size: uselessBlockPart.size, - gasLimit: touple.parentGasLimit, - gasUsed: touple.parentGasLimit / 2, + gasLimit: tuple.parentGasLimit, + gasUsed: tuple.parentGasLimit / 2, baseFeePerGas: Web3.InitialBaseFee, timestamp: uselessBlockPart.timestamp, transactions: uselessBlockPart.transactions, uncles: uselessBlockPart.uncles) - let current = Block(number: touple.parentNumber + 1, + let current = Block(number: tuple.parentNumber + 1, hash: uselessBlockPart.hash, parentHash: uselessBlockPart.parentHash, nonce: uselessBlockPart.nonce, @@ -93,16 +93,16 @@ class EIP1559BlockTests: LocalTestCase { totalDifficulty: uselessBlockPart.totalDifficulty, extraData: uselessBlockPart.extraData, size: uselessBlockPart.size, - gasLimit: touple.currentGasLimit, - gasUsed: touple.currentGasLimit / 2, + gasLimit: tuple.currentGasLimit, + gasUsed: tuple.currentGasLimit / 2, baseFeePerGas: Web3.InitialBaseFee, timestamp: uselessBlockPart.timestamp, transactions: uselessBlockPart.transactions, uncles: uselessBlockPart.uncles) - if touple.is1559 { + if tuple.is1559 { XCTAssertTrue(Web3.isEip1559Block(parent: parent, current: current), - "Shoult not fail, got parent: \(parent.gasLimit), current: \(current.gasLimit)") + "Should not fail, got parent: \(parent.gasLimit), current: \(current.gasLimit)") } else { XCTAssertFalse(Web3.isEip1559Block(parent: parent, current: current), "Should fail, got parent: \(parent.gasLimit), current: \(current.gasLimit)") @@ -124,8 +124,8 @@ class EIP1559BlockTests: LocalTestCase { (Web3.InitialBaseFee, 12_965_000, 20000000, 11000000, 1012500000) // current above target ] - headerArray.forEach { (touple: (parentBaseFee: BigUInt, parentNumber: BigUInt, parentGasLimit: BigUInt, parentGasUsed: BigUInt, expectedBaseFee: BigUInt)) in - let parent = Block(number: touple.parentNumber, + headerArray.forEach { (tuple: (parentBaseFee: BigUInt, parentNumber: BigUInt, parentGasLimit: BigUInt, parentGasUsed: BigUInt, expectedBaseFee: BigUInt)) in + let parent = Block(number: tuple.parentNumber, hash: uselessBlockPart.hash, parentHash: uselessBlockPart.parentHash, nonce: uselessBlockPart.nonce, @@ -139,8 +139,8 @@ class EIP1559BlockTests: LocalTestCase { totalDifficulty: uselessBlockPart.totalDifficulty, extraData: uselessBlockPart.extraData, size: uselessBlockPart.size, - gasLimit: touple.parentGasLimit, - gasUsed: touple.parentGasUsed, + gasLimit: tuple.parentGasLimit, + gasUsed: tuple.parentGasUsed, baseFeePerGas: Web3.InitialBaseFee, timestamp: uselessBlockPart.timestamp, transactions: uselessBlockPart.transactions, @@ -148,7 +148,7 @@ class EIP1559BlockTests: LocalTestCase { let calculatedBaseFee = Web3.calcBaseFee(parent) - XCTAssertEqual(calculatedBaseFee, touple.expectedBaseFee, "Base fee calculation fails: should be \(touple.expectedBaseFee), got: \(String(describing: calculatedBaseFee))") + XCTAssertEqual(calculatedBaseFee, tuple.expectedBaseFee, "Base fee calculation fails: should be \(tuple.expectedBaseFee), got: \(String(describing: calculatedBaseFee))") } } } diff --git a/Tests/web3swiftTests/localTests/EIP681Tests.swift b/Tests/web3swiftTests/localTests/EIP681Tests.swift index 2f347bf59..1fbd027fc 100755 --- a/Tests/web3swiftTests/localTests/EIP681Tests.swift +++ b/Tests/web3swiftTests/localTests/EIP681Tests.swift @@ -83,7 +83,7 @@ class EIP681Tests: XCTestCase { func testENSParsing() async throws { let testAddress = "somename.eth" - let eip681Code = await Web3.EIP681CodeParser.parse("ethereum:\(testAddress)/transfer?address=somename.eth&uint256=1") + let eip681Code = await Web3.EIP681CodeParser.parse("ethereum:\(testAddress)@1/transfer?address=somename.eth&uint256=1") XCTAssert(eip681Code != nil) guard let eip681Code = eip681Code else { return } switch eip681Code.targetAddress { @@ -93,6 +93,11 @@ class EIP681Tests: XCTestCase { XCTAssertEqual(address, testAddress) } + guard eip681Code.parameters.count > 1 else { + XCTFail("'eip681Code.parameters.count' must be at least 2.") + return + } + XCTAssertEqual(eip681Code.functionName, "transfer") XCTAssertEqual(eip681Code.parameters[0].type, .address) /// `eip681Code.parameters[0].value` is not checked as it's fetched from remote and is unknown. @@ -105,7 +110,7 @@ class EIP681Tests: XCTestCase { func testENSParsingWithEncoding() async throws { let testAddress = "somename.eth" - let eip681Code = await Web3.EIP681CodeParser.parse("ethereum:\(testAddress)/transfer?address=somename.eth&uint256=1".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!) + let eip681Code = await Web3.EIP681CodeParser.parse("ethereum:\(testAddress)@1/transfer?address=somename.eth&uint256=1".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!) XCTAssert(eip681Code != nil) guard let eip681Code = eip681Code else { return } switch eip681Code.targetAddress { @@ -115,6 +120,11 @@ class EIP681Tests: XCTestCase { XCTAssertEqual(address, testAddress) } + guard eip681Code.parameters.count > 1 else { + XCTFail("'eip681Code.parameters.count' must be at least 2.") + return + } + XCTAssertEqual(eip681Code.functionName, "transfer") XCTAssertEqual(eip681Code.parameters[0].type, .address) /// `eip681Code.parameters[0].value` is not checked as it's fetched from remote and is unknown. @@ -284,24 +294,24 @@ class EIP681Tests: XCTestCase { eip681Link.functionName = "setData" eip681Link.parameters = [Web3.EIP681Code.EIP681Parameter(type: .array(type: .bytes(length: 32), length: 0), value: [Data.fromHex("0x1234789565875498655487123478956587549865548712347895658754980000")!, - Data.fromHex("0x1234789565875498655487123478956587549865548712347895658754986554")!] as AnyObject), + Data.fromHex("0x1234789565875498655487123478956587549865548712347895658754986554")!]), Web3.EIP681Code.EIP681Parameter(type: .array(type: .dynamicBytes, length: 0), value: [Data.fromHex("0x12345607")!, - Data.fromHex("0x8965abcdef")!] as AnyObject), + Data.fromHex("0x8965abcdef")!]), Web3.EIP681Code.EIP681Parameter(type: .uint(bits: 256), - value: 98986565 as AnyObject), + value: 98986565), Web3.EIP681Code.EIP681Parameter(type: .int(bits: 256), - value: 155445566 as AnyObject), + value: 155445566), Web3.EIP681Code.EIP681Parameter(type: .address, - value: EthereumAddress("0x9aBbDB06A61cC686BD635484439549D45c2449cc")! as AnyObject), + value: EthereumAddress("0x9aBbDB06A61cC686BD635484439549D45c2449cc")!), Web3.EIP681Code.EIP681Parameter(type: .bytes(length: 5), - value: "0x9aBbDB06A6" as AnyObject), + value: "0x9aBbDB06A6"), Web3.EIP681Code.EIP681Parameter(type: .bytes(length: 3), - value: Data.fromHex("0x9aBbDB")! as AnyObject), + value: Data.fromHex("0x9aBbDB")!), Web3.EIP681Code.EIP681Parameter(type: .dynamicBytes, - value: Data.fromHex("0x11009aBbDB87879898656545")! as AnyObject), + value: Data.fromHex("0x11009aBbDB87879898656545")!), Web3.EIP681Code.EIP681Parameter(type: .string, - value: "this is EIP681 query parameter string" as AnyObject)] + value: "this is EIP681 query parameter string")] let unencodedResult = "ethereum:0x9aBbDB06A61cC686BD635484439549D45c2449cc/setData?bytes32[]=[0x1234789565875498655487123478956587549865548712347895658754980000,0x1234789565875498655487123478956587549865548712347895658754986554]&bytes[]=[0x12345607,0x8965abcdef]&uint256=98986565&int256=155445566&address=0x9aBbDB06A61cC686BD635484439549D45c2449cc&bytes5=0x9abbdb06a6&bytes3=0x9abbdb&bytes=0x11009abbdb87879898656545&string=this is EIP681 query parameter string" diff --git a/Tests/web3swiftTests/localTests/EIP712Tests.swift b/Tests/web3swiftTests/localTests/EIP712Tests.swift index 538c651cf..3f527d2cf 100644 --- a/Tests/web3swiftTests/localTests/EIP712Tests.swift +++ b/Tests/web3swiftTests/localTests/EIP712Tests.swift @@ -17,8 +17,8 @@ class EIP712Tests: LocalTestCase { payable: false) let object = ABI.Element.function(function) let safeTxData = object.encodeParameters([ - EthereumAddress("0x41B5844f4680a8C38fBb695b7F9CFd1F64474a72")! as AnyObject, - amountLinen as AnyObject + EthereumAddress("0x41B5844f4680a8C38fBb695b7F9CFd1F64474a72")!, + amountLinen ])! let operation: EIP712.UInt8 = 1 let safeTxGas = EIP712.UInt256(250000) @@ -68,8 +68,8 @@ class EIP712Tests: LocalTestCase { payable: false) let object = ABI.Element.function(function) let safeTxData = object.encodeParameters([ - EthereumAddress("0x41B5844f4680a8C38fBb695b7F9CFd1F64474a72")! as AnyObject, - amount as AnyObject + EthereumAddress("0x41B5844f4680a8C38fBb695b7F9CFd1F64474a72")!, + amount ])! let operation: EIP712.UInt8 = 1 let safeTxGas = EIP712.UInt256(250000) diff --git a/Tests/web3swiftTests/localTests/ERC20ClassTests.swift b/Tests/web3swiftTests/localTests/ERC20ClassTests.swift index c9ba5b75e..9c95addca 100755 --- a/Tests/web3swiftTests/localTests/ERC20ClassTests.swift +++ b/Tests/web3swiftTests/localTests/ERC20ClassTests.swift @@ -22,7 +22,7 @@ class ERC20ClassTests: LocalTestCase { } /// We had an issue with multiple async reads performed at the same point in time /// sometimes returning wrong values (actually values of each other). - /// The issue is most likely related to async/await feautre of Swift. + /// The issue is most likely related to async/await feature of Swift. /// Due to that was decided to add a loop to execute the same async calls that checks the same ERC20 properties /// multiple times. All calls must succeed. /// Each run executes 3 async read operations. diff --git a/Tests/web3swiftTests/localTests/ERC20Tests.swift b/Tests/web3swiftTests/localTests/ERC20Tests.swift index 231719d51..f569640b5 100755 --- a/Tests/web3swiftTests/localTests/ERC20Tests.swift +++ b/Tests/web3swiftTests/localTests/ERC20Tests.swift @@ -26,10 +26,10 @@ class ERC20Tests: LocalTestCase { let addressOfUser = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901")! let contract = web3.contract(Web3.Utils.erc20ABI, at: receipt.contractAddress!, abiVersion: 2)! - guard let readTX = contract.createReadOperation("balanceOf", parameters: [addressOfUser] as [AnyObject]) else {return XCTFail()} + guard let readTX = contract.createReadOperation("balanceOf", parameters: [addressOfUser]) else { return XCTFail() } readTX.transaction.from = addressOfUser - let tokenBalance = try await readTX.callContractMethod() - guard let bal = tokenBalance["0"] as? BigUInt else {return XCTFail()} + let tokenBalanceResponse = try await readTX.callContractMethod() + XCTAssertNotNil(tokenBalanceResponse["0"] as? BigUInt) } // FIXME: Make me work @@ -49,7 +49,7 @@ class ERC20Tests: LocalTestCase { // let method = "transfer" // let tx = contract.write( // method, -// parameters: [toAddress, amount] as [AnyObject], +// parameters: [toAddress, amount], // extraData: Data(), // transaction: options)! // } diff --git a/Tests/web3swiftTests/localTests/EthereumContractTest.swift b/Tests/web3swiftTests/localTests/EthereumContractTest.swift index 06251e388..be6c6cd4f 100644 --- a/Tests/web3swiftTests/localTests/EthereumContractTest.swift +++ b/Tests/web3swiftTests/localTests/EthereumContractTest.swift @@ -65,10 +65,10 @@ class EthereumContractTest: LocalTestCase { func test_encodeMethodBasedOnNameWithParameters() async throws { let web3 = try await Web3.new(LocalTestCase.url) let contract = try XCTUnwrap(web3.contract(EthereumContractTest.overloadedFunctionsABI, at: EthereumAddress("0x6394b37Cf80A7358b38068f0CA4760ad49983a1B"))) - let parameters: [AnyObject] = [ + let parameters: [Any] = [ [Data.randomBytes(length: 32), Data.randomBytes(length: 32)], [Data.randomBytes(length: 32), Data.randomBytes(length: 32)] - ] as [AnyObject] + ] let functionNameWithParameters = "setData(bytes32[],bytes[])" let transaction = contract.createWriteOperation(functionNameWithParameters, parameters: parameters) XCTAssertNotNil(transaction) @@ -88,7 +88,7 @@ class EthereumContractTest: LocalTestCase { func test_encodeMethodBasedOnHexSignature() async throws { let web3 = try await Web3.new(LocalTestCase.url) let contract = try XCTUnwrap(web3.contract(EthereumContractTest.overloadedFunctionsABI, at: EthereumAddress("0x6394b37Cf80A7358b38068f0CA4760ad49983a1B"))) - let parameters: [AnyObject] = [Data.randomBytes(length: 32), Data.randomBytes(length: 32)] as [AnyObject] + let parameters: [Any] = [Data.randomBytes(length: 32), Data.randomBytes(length: 32)] let functionSignature = getFuncSignature("setData(bytes32,bytes)") let transaction = contract.createWriteOperation(functionSignature, parameters: parameters) XCTAssertNotNil(transaction) diff --git a/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift b/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift index 852137efd..407115b08 100755 --- a/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift +++ b/Tests/web3swiftTests/localTests/PersonalSignatureTests.swift @@ -64,13 +64,13 @@ class PersonalSignatureTests: XCTestCase { // Calling contract contract = web3.contract(abiString, at: receipt.contractAddress!)! - var tx = contract.createReadOperation("hashPersonalMessage", parameters: [message as AnyObject]) + var tx = contract.createReadOperation("hashPersonalMessage", parameters: [message]) tx?.transaction.from = expectedAddress var result = try await tx!.callContractMethod() guard let hash = result["hash"]! as? Data else { return XCTFail() } XCTAssert(Utilities.hashPersonalMessage(message.data(using: .utf8)!)! == hash) - tx = contract.createReadOperation("recoverSigner", parameters: [message, unmarshalledSignature.v, Data(unmarshalledSignature.r), Data(unmarshalledSignature.s)] as [AnyObject]) + tx = contract.createReadOperation("recoverSigner", parameters: [message, unmarshalledSignature.v, Data(unmarshalledSignature.r), Data(unmarshalledSignature.s)]) tx?.transaction.from = expectedAddress result = try await tx!.callContractMethod() guard let signer = result["signer"]! as? EthereumAddress else { return XCTFail() } diff --git a/Tests/web3swiftTests/localTests/PromisesTests.swift b/Tests/web3swiftTests/localTests/PromisesTests.swift index 8063003d9..434c6389c 100755 --- a/Tests/web3swiftTests/localTests/PromisesTests.swift +++ b/Tests/web3swiftTests/localTests/PromisesTests.swift @@ -41,7 +41,7 @@ // let allAddresses = try await web3.eth.ownedAccounts() // let contract = web3.contract(Web3.Utils.estimateGasTestABI, at: nil, abiVersion: 2)! // -// let parameters = [] as [AnyObject] +// let parameters = [] // let deployTx = contract.deploy(bytecode: bytecode, parameters: parameters)! // deployTx.transaction.from = allAddresses[0] // deployTx.transaction.gasLimitPolicy = .manual(3000000) @@ -80,7 +80,7 @@ // // // MARK: Writing Data flow // guard let tx1 = contract.write("test", -// parameters: [amount1] as [AnyObject], +// parameters: [amount1], // extraData: Data(), // transaction: options) else { // return @@ -93,7 +93,7 @@ // // // MARK: Writing Data flow // guard let tx2 = contract.write("test", -// parameters: [amount2] as [AnyObject], +// parameters: [amount2], // extraData: Data(), // transaction: options) else { // return @@ -122,7 +122,7 @@ // let token = web3.contract(Web3.Utils.erc20ABI, at: receipt.contractAddress, abiVersion: 2)! // // let userAddress = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901")! -// let tokenBalance = try await token.read("balanceOf", parameters: [userAddress] as [AnyObject])!.decodedData() +// let tokenBalance = try await token.read("balanceOf", parameters: [userAddress])!.decodedData() // guard let bal = tokenBalance["0"] as? BigUInt else {return XCTFail()} // ) // } diff --git a/Tests/web3swiftTests/localTests/ST20AndSecurityTokenTests.swift b/Tests/web3swiftTests/localTests/ST20AndSecurityTokenTests.swift index 84782bbeb..285b2641f 100644 --- a/Tests/web3swiftTests/localTests/ST20AndSecurityTokenTests.swift +++ b/Tests/web3swiftTests/localTests/ST20AndSecurityTokenTests.swift @@ -37,11 +37,11 @@ class ST20AndSecurityTokenTests: XCTestCase { } switch function.name { case "symbol": - return ABIEncoder.encode(types: [.string], values: [expectedSymbol] as [AnyObject])! + return ABIEncoder.encode(types: [.string], values: [expectedSymbol])! case "name": - return ABIEncoder.encode(types: [.string], values: [expectedName] as [AnyObject])! + return ABIEncoder.encode(types: [.string], values: [expectedName])! case "decimals": - return ABIEncoder.encode(types: [.uint(bits: 8)], values: [expectedDecimals] as [AnyObject])! + return ABIEncoder.encode(types: [.uint(bits: 8)], values: [expectedDecimals])! default: // Unexpected function called XCTFail("Called function '\(String(describing: function.name))' which wasn't supposed to be called.") @@ -71,12 +71,12 @@ class ST20AndSecurityTokenTests: XCTestCase { case "balanceOf": let address = function.decodeInputData(transaction.data)?["0"] as? EthereumAddress XCTAssertEqual(address, userAddress) - return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedBalance] as [AnyObject])! + return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedBalance])! case "allowance": let transactionInput = function.decodeInputData(transaction.data) XCTAssertEqual(transactionInput?["0"] as? EthereumAddress, userAddress) XCTAssertEqual(transactionInput?["1"] as? EthereumAddress, delegate) - return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedAllowance] as [AnyObject])! + return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedAllowance])! default: // Unexpected function called XCTFail("Called function '\(String(describing: function.name))' which wasn't supposed to be called.") @@ -98,7 +98,7 @@ class ST20AndSecurityTokenTests: XCTestCase { return Data() } if function.name == "investorCount" { - return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedNumberOfInvestors] as [AnyObject])! + return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedNumberOfInvestors])! } // Unexpected function called XCTFail("Called function '\(String(describing: function.name))' which wasn't supposed to be called.") @@ -119,7 +119,7 @@ class ST20AndSecurityTokenTests: XCTestCase { } switch function.name { case "granularity": - return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedGranularity] as [AnyObject])! + return ABIEncoder.encode(types: [.uint(bits: 256)], values: [expectedGranularity])! default: // Unexpected function called XCTFail("Called function '\(String(describing: function.name))' which wasn't supposed to be called.") diff --git a/Tests/web3swiftTests/localTests/TestHelpers.swift b/Tests/web3swiftTests/localTests/TestHelpers.swift index 674771ec9..ce049fce4 100644 --- a/Tests/web3swiftTests/localTests/TestHelpers.swift +++ b/Tests/web3swiftTests/localTests/TestHelpers.swift @@ -22,12 +22,12 @@ class TestHelpers { let contract = web3.contract(abiString, at: nil, abiVersion: 2)! // FIXME: This should be zipped, because Arrays don't guarantee it's elements order - let parameters = [ + let parameters: [Any] = [ "web3swift", "w3s", EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901")!, 1024 - ] as [AnyObject] + ] let deployTx = contract.prepareDeploy(bytecode: bytecode, constructor: contract.contract.constructor, parameters: parameters)! diff --git a/Tests/web3swiftTests/localTests/TransactionsTests.swift b/Tests/web3swiftTests/localTests/TransactionsTests.swift index 02a560b2f..1a39e3bf3 100755 --- a/Tests/web3swiftTests/localTests/TransactionsTests.swift +++ b/Tests/web3swiftTests/localTests/TransactionsTests.swift @@ -471,7 +471,6 @@ class TransactionsTests: XCTestCase { // check that we recovered the address correctly XCTAssertEqual(jsonTxn.sender!.address, expectedAddress.address, "Recovered Address Mismatch") } catch { - return XCTFail(String(describing: error)) } } @@ -594,7 +593,7 @@ class TransactionsTests: XCTestCase { } // ***** Legacy Tests ***** - // TODO: Replace `XCTAssert` with more explicite `XCTAssertEqual`, where Applicable + // TODO: Replace `XCTAssert` with more explicit `XCTAssertEqual`, where Applicable func testDirectTransaction() throws { do { @@ -657,7 +656,7 @@ class TransactionsTests: XCTestCase { let details = try await web3.eth.transactionDetails(txHash) - // FIXME: Reenable this test. + // FIXME: Re-enable this test. // XCTAssertEqual(details.transaction.gasLimit, BigUInt(78423)) } catch Web3Error.nodeError(let descr) { guard descr == "insufficient funds for gas * price + value" else {return XCTFail()} diff --git a/Tests/web3swiftTests/localTests/UncategorizedTests.swift b/Tests/web3swiftTests/localTests/UncategorizedTests.swift index dc5600da9..ccd1056b1 100755 --- a/Tests/web3swiftTests/localTests/UncategorizedTests.swift +++ b/Tests/web3swiftTests/localTests/UncategorizedTests.swift @@ -116,15 +116,15 @@ class UncategorizedTests: XCTestCase { XCTAssert(contract != nil) let allMethods = contract!.contract.allMethods let userDeviceCount = try await contract! - .createReadOperation("userDeviceCount", parameters: [addr as AnyObject])? + .createReadOperation("userDeviceCount", parameters: [addr])? .callContractMethod() let totalUsers = try await contract! - .createReadOperation("totalUsers", parameters: [])? + .createReadOperation("totalUsers")? .callContractMethod() let user = try await contract! - .createReadOperation("users", parameters: [0 as AnyObject])? + .createReadOperation("users", parameters: [0])? .callContractMethod() diff --git a/Tests/web3swiftTests/localTests/UserCases.swift b/Tests/web3swiftTests/localTests/UserCases.swift index 49a95184f..c6377dda9 100755 --- a/Tests/web3swiftTests/localTests/UserCases.swift +++ b/Tests/web3swiftTests/localTests/UserCases.swift @@ -22,7 +22,7 @@ class UserCases: XCTestCase { let (web3, _, receipt, abiString) = try await TestHelpers.localDeployERC20() let account = EthereumAddress("0xe22b8979739D724343bd002F9f432F5990879901")! let contract = web3.contract(abiString, at: receipt.contractAddress!)! - let readTransaction = contract.createReadOperation("balanceOf", parameters: [account] as [AnyObject])! + let readTransaction = contract.createReadOperation("balanceOf", parameters: [account])! readTransaction.transaction.from = account let response = try await readTransaction.callContractMethod() let balance = response["0"] as? BigUInt @@ -76,7 +76,7 @@ class UserCases: XCTestCase { let allAddresses = try await web3.eth.ownedAccounts() let contract = web3.contract(Web3.Utils.estimateGasTestABI, at: nil, abiVersion: 2)! - let parameters = [AnyObject]() + let parameters = [Any]() let deployTx = contract.prepareDeploy(bytecode: bytecode, parameters: parameters)! deployTx.transaction.from = allAddresses[0] let policies = Policies(gasLimitPolicy: .manual(3000000)) diff --git a/Tests/web3swiftTests/localTests/UtilitiesTests.swift b/Tests/web3swiftTests/localTests/UtilitiesTests.swift index 53a6761fc..5751afde0 100644 --- a/Tests/web3swiftTests/localTests/UtilitiesTests.swift +++ b/Tests/web3swiftTests/localTests/UtilitiesTests.swift @@ -47,4 +47,39 @@ class UtilitiesTests: XCTestCase { XCTAssertEqual(test.input.decimals, test.output) } } + + func testPublicKeyWithNoPrefixToAddress() throws { + var address = Utilities.publicToAddress(Data.fromHex("0x18ed2e1ec629e2d3dae7be1103d4f911c24e0c80e70038f5eb5548245c475f504c220d01e1ca419cb1ba4b3393b615e99dd20aa6bf071078f70fd949008e7411")!)?.address + XCTAssertEqual(address, "0x28828f43df370651AC5A6cFd02fBD0885Fbb3c00") + address = Utilities.publicToAddress(Data.fromHex("0x52972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab288742f4dc97d9edb6fd946babc002fdfb06f26caf117b9405ed79275763fdb1c")!)?.address + XCTAssertEqual(address, "0x6eDBe1F6D48FbF1b053D6c9FA7997C710B84f55F") + } + + func testPublicKeyWithPrefixToAddress() throws { + var address = Utilities.publicToAddress(Data.fromHex("0x0418ed2e1ec629e2d3dae7be1103d4f911c24e0c80e70038f5eb5548245c475f504c220d01e1ca419cb1ba4b3393b615e99dd20aa6bf071078f70fd949008e7411")!)?.address + XCTAssertEqual(address, "0x28828f43df370651AC5A6cFd02fBD0885Fbb3c00") + address = Utilities.publicToAddress(Data.fromHex("0x0452972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab288742f4dc97d9edb6fd946babc002fdfb06f26caf117b9405ed79275763fdb1c")!)?.address + XCTAssertEqual(address, "0x6eDBe1F6D48FbF1b053D6c9FA7997C710B84f55F") + } + + func testPublicKeyWithInvalidPrefixToAddress() throws { + var address = Utilities.publicToAddress(Data.fromHex("0x0318ed2e1ec629e2d3dae7be1103d4f911c24e0c80e70038f5eb5548245c475f504c220d01e1ca419cb1ba4b3393b615e99dd20aa6bf071078f70fd949008e7411")!)?.address + XCTAssertEqual(address, nil) + address = Utilities.publicToAddress(Data.fromHex("0x0152972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab288742f4dc97d9edb6fd946babc002fdfb06f26caf117b9405ed79275763fdb1c")!)?.address + XCTAssertEqual(address, nil) + } + + func testCompressedPublicKeyToAddress() throws { + var address = Utilities.publicToAddress(Data.fromHex("0x0318ed2e1ec629e2d3dae7be1103d4f911c24e0c80e70038f5eb5548245c475f50")!)?.address + XCTAssertEqual(address, "0x28828f43df370651AC5A6cFd02fBD0885Fbb3c00") + address = Utilities.publicToAddress(Data.fromHex("0x0252972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2")!)?.address + XCTAssertEqual(address, "0x6eDBe1F6D48FbF1b053D6c9FA7997C710B84f55F") + } + + func testCompressedPublicKeyWithInvalidPrefixToAddress() throws { + var address = Utilities.publicToAddress(Data.fromHex("0x0718ed2e1ec629e2d3dae7be1103d4f911c24e0c80e70038f5eb5548245c475f50")!)?.address + XCTAssertEqual(address, nil) + address = Utilities.publicToAddress(Data.fromHex("0x0852972572d465d016d4c501887b8df303eee3ed602c056b1eb09260dfa0da0ab2")!)?.address + XCTAssertEqual(address, nil) + } } diff --git a/Tests/web3swiftTests/remoteTests/EtherscanTransactionCheckerTests.swift b/Tests/web3swiftTests/remoteTests/EtherscanTransactionCheckerTests.swift index 68d91f933..c58d2fa44 100644 --- a/Tests/web3swiftTests/remoteTests/EtherscanTransactionCheckerTests.swift +++ b/Tests/web3swiftTests/remoteTests/EtherscanTransactionCheckerTests.swift @@ -9,12 +9,12 @@ import XCTest final class EtherscanTransactionCheckerTests: XCTestCase { private var testApiKey: String { "4HVPVMV1PN6NGZDFXZIYKEZRP53IA41KVC" } private var vitaliksAddress: String { "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B" } - private var emptyAddress: String { "0x1BeY3KhtHpfATH5Yqxz9d8Z1XbqZFSXtK7" } + private var emptyAddress: String { "0x3a0cd085155dc74cdddf3196f23c8cec9b217dd8" } func testHasTransactions() async throws { let sut = EtherscanTransactionChecker(urlSession: URLSession.shared, apiKey: testApiKey) - - let result = try await sut.hasTransactions(address: vitaliksAddress) + + let result = try await sut.hasTransactions(ethereumAddress: try XCTUnwrap(EthereumAddress(vitaliksAddress))) XCTAssertTrue(result) } @@ -22,7 +22,8 @@ final class EtherscanTransactionCheckerTests: XCTestCase { func testHasNotTransactions() async throws { let sut = EtherscanTransactionChecker(urlSession: URLSession.shared, apiKey: testApiKey) - let result = try await sut.hasTransactions(address: emptyAddress) + let ethAddr = try XCTUnwrap(EthereumAddress(emptyAddress)) + let result = try await sut.hasTransactions(ethereumAddress: ethAddr) XCTAssertFalse(result) } @@ -33,31 +34,31 @@ final class EtherscanTransactionCheckerTests: XCTestCase { urlSessionMock.response = (Data(), try XCTUnwrap(HTTPURLResponse(url: try XCTUnwrap(URL(string: "https://")), statusCode: 500, httpVersion: nil, headerFields: nil))) let sut = EtherscanTransactionChecker(urlSession: urlSessionMock, apiKey: testApiKey) - _ = try await sut.hasTransactions(address: vitaliksAddress) + _ = try await sut.hasTransactions(ethereumAddress: try XCTUnwrap(EthereumAddress(vitaliksAddress))) XCTFail("Network must throw an error") - } catch { - XCTAssertTrue(true) + } catch let EtherscanTransactionCheckerError.network(statusCode) { + XCTAssertEqual(statusCode, 500) } } func testInitURLError() async throws { do { - let sut = EtherscanTransactionChecker(urlSession: URLSessionMock(), apiKey: testApiKey) + let sut = EtherscanTransactionChecker(urlSession: URLSessionMock(), apiKey: " ") - _ = try await sut.hasTransactions(address: " ") + _ = try await sut.hasTransactions(ethereumAddress: try XCTUnwrap(EthereumAddress(vitaliksAddress))) XCTFail("URL init must throw an error") - } catch { - XCTAssertTrue(error is EtherscanTransactionCheckerError) + } catch EtherscanTransactionCheckerError.invalidUrl { + XCTAssertTrue(true) } } func testWrongApiKey() async throws { do { - let sut = EtherscanTransactionChecker(urlSession: URLSession.shared, apiKey: "") + let sut = EtherscanTransactionChecker(urlSession: URLSession.shared, apiKey: "-") - _ = try await sut.hasTransactions(address: "") + _ = try await sut.hasTransactions(ethereumAddress: try XCTUnwrap(EthereumAddress(vitaliksAddress))) XCTFail("API not returns a valid response") } catch DecodingError.typeMismatch { diff --git a/Tests/web3swiftTests/remoteTests/InfuraTests.swift b/Tests/web3swiftTests/remoteTests/InfuraTests.swift index 88d630f45..c53020293 100755 --- a/Tests/web3swiftTests/remoteTests/InfuraTests.swift +++ b/Tests/web3swiftTests/remoteTests/InfuraTests.swift @@ -94,7 +94,7 @@ class InfuraTests: XCTestCase { // let web3 = Web3.InfuraRinkebyWeb3(accessToken: Constants.infuraToken) // let contract = web3.contract(jsonString, at: contractAddress, abiVersion: 2) // guard let eventParser = contract?.createEventParser("Deposit", filter: nil) else {return XCTFail()} -// let pres = try eventParser.parseBlockByNumber(UInt64(2138657)) -// XCTAssert(pres.count == 1) +// let present = try eventParser.parseBlockByNumber(UInt64(2138657)) +// XCTAssert(present.count == 1) // } } diff --git a/Tests/web3swiftTests/remoteTests/RemoteParsingTests.swift b/Tests/web3swiftTests/remoteTests/RemoteParsingTests.swift index e42e2b2e0..b4b272b20 100755 --- a/Tests/web3swiftTests/remoteTests/RemoteParsingTests.swift +++ b/Tests/web3swiftTests/remoteTests/RemoteParsingTests.swift @@ -25,18 +25,18 @@ class RemoteParsingTests: XCTestCase { // // guard let eventParser = contract?.createEventParser("Transfer", filter: nil) else {return XCTFail()} // -// let pres = try eventParser.parseBlockByNumber(UInt64(5200088)) +// let present = try eventParser.parseBlockByNumber(UInt64(5200088)) // -// XCTAssert(pres.count == 1) +// XCTAssert(present.count == 1) // -// let decoded = pres[0].decodedResult +// let decoded = present[0].decodedResult // // XCTAssert(decoded["name"] as! String == "Transfer") // XCTAssert(decoded["_to"] as! EthereumAddress == EthereumAddress("0xa5dcf6e0fee38f635c4a8d50d90e24400ed547d2")!) // XCTAssert(decoded["_from"] as! EthereumAddress == EthereumAddress("0xdbf493e8d7db835192c02b992bd1ab72e96fd2e3")!) // XCTAssert(decoded["_value"] as! BigUInt == BigUInt("3946fe37ffce3a0000", radix: 16)!) -// XCTAssert(pres[0].contractAddress == EthereumAddress("0x45245bc59219eeaaf6cd3f382e078a461ff9de7b")!) -// XCTAssert(pres[0].transactionReceipt!.transactionHash.toHexString().addHexPrefix() == "0xcb235e8c6ecda032bc82c1084d2159ab82e7e4de35be703da6e80034bc577673") +// XCTAssert(present[0].contractAddress == EthereumAddress("0x45245bc59219eeaaf6cd3f382e078a461ff9de7b")!) +// XCTAssert(present[0].transactionReceipt!.transactionHash.toHexString().addHexPrefix() == "0xcb235e8c6ecda032bc82c1084d2159ab82e7e4de35be703da6e80034bc577673") // } // func testEventParsing2usingABIv2() throws { @@ -44,8 +44,8 @@ class RemoteParsingTests: XCTestCase { // let web3 = Web3.InfuraMainnetWeb3(accessToken: Constants.infuraToken) // let contract = web3.contract(jsonString, at: nil, abiVersion: 2) // guard let eventParser = contract?.createEventParser("Transfer", filter: nil) else {return XCTFail()} -// let pres = try eventParser.parseBlockByNumber(UInt64(5200120)) -// XCTAssert(pres.count == 81) +// let present = try eventParser.parseBlockByNumber(UInt64(5200120)) +// XCTAssert(present.count == 81) // } // func testEventParsing3usingABIv2() throws { @@ -62,8 +62,8 @@ class RemoteParsingTests: XCTestCase { // } // // for i in currentBlockAsInt-1 ... currentBlockAsInt { -// let pres = try eventParser.parseBlockByNumber(i) -// for p in pres { +// let present = try eventParser.parseBlockByNumber(i) +// for p in present { // + "\n") // // .addHexPrefix() + "\n") @@ -82,8 +82,8 @@ class RemoteParsingTests: XCTestCase { // filter.addresses = [EthereumAddress("0x53066cddbc0099eb6c96785d9b3df2aaeede5da3")!] // filter.parameterFilters = [([EthereumAddress("0xefdcf2c36f3756ce7247628afdb632fa4ee12ec5")!] as [EventFilterable]), ([EthereumAddress("0xd5395c132c791a7f46fa8fc27f0ab6bacd824484")!] as [EventFilterable])] // guard let eventParser = contract?.createEventParser("Transfer", filter: filter) else {return XCTFail()} -// let pres = try eventParser.parseBlockByNumber(UInt64(5200120)) -// XCTAssert(pres.count == 1) +// let present = try eventParser.parseBlockByNumber(UInt64(5200120)) +// XCTAssert(present.count == 1) // //TODO: - Make following assert //// with filter would be //// [web3swift_iOS.EventLog(address: web3swift_iOS.EthereumAddress(_address: "0x53066cddbc0099eb6c96785d9b3df2aaeede5da3", type: web3swift_iOS.EthereumAddress.AddressType.normal), data: 32 bytes, logIndex: 132, removed: false, topics: [32 bytes, 32 bytes, 32 bytes])], status: web3swift_iOS.TransactionReceipt.TXStatus.ok, logsBloom: Optional(web3swift_iOS.EthereumBloomFilter(bytes: 256 bytes))), contractAddress: web3swift_iOS.EthereumAddress(_address: "0x53066cddbc0099eb6c96785d9b3df2aaeede5da3", type: web3swift_iOS.EthereumAddress.AddressType.normal), decodedResult: ["name": "Transfer", "1": web3swift_iOS.EthereumAddress(_address: "0xd5395c132c791a7f46fa8fc27f0ab6bacd824484", type: web3swift_iOS.EthereumAddress.AddressType.normal), "_from": web3swift_iOS.EthereumAddress(_address: "0xefdcf2c36f3756ce7247628afdb632fa4ee12ec5", type: web3swift_iOS.EthereumAddress.AddressType.normal), "_to": web3swift_iOS.EthereumAddress(_address: "0xd5395c132c791a7f46fa8fc27f0ab6bacd824484", type: web3swift_iOS.EthereumAddress.AddressType.normal), "2": 5000000000000000000, "0": web3swift_iOS.EthereumAddress(_address: "0xefdcf2c36f3756ce7247628afdb632fa4ee12ec5", type: web3swift_iOS.EthereumAddress.AddressType.normal), "_value": 5000000000000000000])] diff --git a/Web3Core.podspec b/Web3Core.podspec index 80873eece..0da2cabc9 100644 --- a/Web3Core.podspec +++ b/Web3Core.podspec @@ -2,8 +2,7 @@ Pod::Spec.new do |spec| spec.compiler_flags = '-DCOCOAPODS' spec.name = 'Web3Core' - spec.version = '3.0.6' - spec.module_name = 'Core' + spec.version = '3.1.1' spec.ios.deployment_target = "13.0" spec.osx.deployment_target = "10.15" spec.license = { :type => 'Apache License 2.0', :file => 'LICENSE.md' } @@ -16,5 +15,5 @@ Pod::Spec.new do |spec| spec.dependency 'secp256k1.c', '~> 0.1' spec.dependency 'BigInt', '~> 5.2.0' # no newer version in pods. spec.dependency 'CryptoSwift', '~> 1.5.1' - spec.source_files = "Sources/Core/**/*.swift" + spec.source_files = "Sources/Web3Core/**/*.swift" end diff --git a/web3swift.podspec b/web3swift.podspec index 48d930d88..50da01f53 100755 --- a/web3swift.podspec +++ b/web3swift.podspec @@ -1,4 +1,4 @@ -WEB3CORE_VERSION ||= '3.0.6' +WEB3CORE_VERSION ||= '3.1.1' Pod::Spec.new do |spec| spec.name = 'web3swift'