├── .gitattributes ├── .gitignore ├── .swift-version ├── .swiftlint.yml ├── .travis.yml ├── CONTRIBUTING.md ├── Example ├── .swiftlint.yml ├── Actors │ ├── Actor.swift │ ├── Alice.swift │ ├── Bob.swift │ ├── SimpleActor.swift │ └── Tim.swift ├── Errors │ └── UnknownError.swift ├── Extensions │ └── URL.swift ├── Networks │ ├── GanacheLocalNetwork.swift │ ├── MainnetAlchemyNetwork.swift │ └── MainnetMetamaskNetwork.swift ├── Podfile ├── Podfile.lock ├── Tests │ ├── ABI │ │ ├── Decoding │ │ │ ├── ABICollectionSliceTests.swift │ │ │ ├── ABIDecodingIT.swift │ │ │ ├── ABIMessageTests.swift │ │ │ ├── DecodedABIAddressTests.swift │ │ │ ├── DecodedABIBooleanTests.swift │ │ │ ├── DecodedABIDynamicCollectionTests.swift │ │ │ ├── DecodedABIFixedBytesTests.swift │ │ │ ├── DecodedABINumberTests.swift │ │ │ ├── DecodedABIStringTests.swift │ │ │ └── DecodedABIVariableBytesTests.swift │ │ ├── EncodedABIFunctionTests.swift │ │ ├── EncodedABITupleTests.swift │ │ ├── EncodedContractTests.swift │ │ └── Parameters │ │ │ ├── ABIAddressTests.swift │ │ │ ├── ABIBooleanTests.swift │ │ │ ├── ABIDynamicCollectionTests.swift │ │ │ ├── ABIFixedBytesTests.swift │ │ │ ├── ABIStringTests.swift │ │ │ ├── ABITupleTests.swift │ │ │ ├── ABIUnsignedNumberTests.swift │ │ │ └── ABIVariableBytesTests.swift │ ├── Account │ │ └── EthAutoAccountIT.swift │ ├── Address │ │ ├── ComputedContractAddressTests.swift │ │ └── EthAddressTests.swift │ ├── BlockHash │ │ └── EthBlockHashTests.swift │ ├── Blocks │ │ └── EthBlockTests.swift │ ├── BooleanScalar │ │ ├── AndTests.swift │ │ ├── FalseTests.swift │ │ ├── NumericBooleanTests.swift │ │ ├── SimpleBooleanTests.swift │ │ ├── TernaryTests.swift │ │ └── TrueTests.swift │ ├── BytesScalar │ │ ├── ASCIIStringBytesTests.swift │ │ ├── BytesAsCollectionTests.swift │ │ ├── BytesAtTests.swift │ │ ├── BytesFromCompactHexStringTests.swift │ │ ├── BytesFromHexStringTests.swift │ │ ├── CachedBytesTests.swift │ │ ├── ConcatenatedBytesTests.swift │ │ ├── FirstBitTests.swift │ │ ├── FirstByteTests.swift │ │ ├── FirstBytesTests.swift │ │ ├── FixedLengthBytesTests.swift │ │ ├── IntegerBytesTests.swift │ │ ├── Keccak256BytesTests.swift │ │ ├── LastBytesTests.swift │ │ ├── LeadingCompactBytesTests.swift │ │ ├── LeftZeroesPaddedBytesTests.swift │ │ ├── ReversedBytesTests.swift │ │ ├── RightZeroesPaddedBytesTests.swift │ │ ├── SizeBufferedBytesTests.swift │ │ ├── TrailingCompactBytesTests.swift │ │ └── UTF8StringBytesTests.swift │ ├── Collection │ │ └── CollectionSingleTests.swift │ ├── CollectionScalar │ │ ├── CachedCollectionTests.swift │ │ ├── CollectionSuffixTests.swift │ │ ├── ElementAtTests.swift │ │ ├── EnumeratedCollectionTests.swift │ │ ├── GeneratedCollectionTests.swift │ │ ├── MappedCollectionTests.swift │ │ ├── SimpleCollectionTests.swift │ │ ├── SizeConstrainedCollectionTests.swift │ │ └── SizeOfTests.swift │ ├── ContractCall │ │ └── EthContractCallTests.swift │ ├── DecimalScalar │ │ ├── DecimalFromHexTests.swift │ │ └── NormalizedDecimalFromHexTests.swift │ ├── ECRecoverableSignature │ │ └── SECP256k1SignatureTests.swift │ ├── Entropy │ │ └── RandomNonceTests.swift │ ├── GasEstimate │ │ └── EthGasEstimateTests.swift │ ├── GasPrice │ │ └── EthGasPriceTests.swift │ ├── Info.plist │ ├── IntegerScalar │ │ ├── BigEndianIntegerTests.swift │ │ ├── BytesAsIntegerTests.swift │ │ ├── CachedIntegerTests.swift │ │ ├── EthIntegerTests.swift │ │ ├── IntegerTypeSizeTests.swift │ │ ├── IntegersDifferenceTests.swift │ │ ├── IntegersEqualityTests.swift │ │ ├── IntegersProductTests.swift │ │ ├── IntegersQuotientTests.swift │ │ ├── IntegersSumTests.swift │ │ ├── IsNegativeEthIntegerTests.swift │ │ ├── NaturalIntegerTests.swift │ │ ├── RangeConstrainedIntegerTests.swift │ │ └── TernaryIntegerTests.swift │ ├── JSON │ │ └── JSONTypeErrorTests.swift │ ├── Network │ │ ├── AlchemyNetworkTests.swift │ │ ├── EthNetworkTests.swift │ │ ├── GanacheLocalNetworkTests.swift │ │ ├── GethNetworkTests.swift │ │ ├── InfuraNetworkTests.swift │ │ ├── MainnetInfuraMetamaskNetworkTests.swift │ │ ├── SimpleNetworkTests.swift │ │ └── VerifiedNetworkTests.swift │ ├── NumberScalar │ │ ├── ArithmeticFunctionsTests.swift │ │ ├── EthNumberTests.swift │ │ ├── HexAsDecimalStringTests.swift │ │ ├── UnsignedNumbersDifferenceTests.swift │ │ ├── UnsignedNumbersEqualityTests.swift │ │ ├── UnsignedNumbersExponentiationTests.swift │ │ ├── UnsignedNumbersProductTests.swift │ │ ├── UnsignedNumbersQuotientTests.swift │ │ └── UnsignedNumbersSumTests.swift │ ├── Other │ │ ├── ByteWidthTests.swift │ │ ├── DataToDecimalTests.swift │ │ ├── DataToHexTests.swift │ │ └── FetchingLogsTests.swift │ ├── Params │ │ ├── BooleanParameterTests.swift │ │ ├── BytesParameterTests.swift │ │ ├── ObjectParameterTests.swift │ │ └── QuantityParameterTests.swift │ ├── PersonalMessageBytes │ │ ├── PersonalMessageBytesTests.swift │ │ └── SignedPersonalMessageBytesTests.swift │ ├── PrivateKey │ │ ├── EthPrivateKeyTests.swift │ │ └── PrivateKeyAddressTests.swift │ ├── Procedures │ │ ├── CachedProcedureTests.swift │ │ ├── ChainIDProcedureTests.swift │ │ ├── ContractCallProcedureTests.swift │ │ ├── EstimateGasProcedureTests.swift │ │ ├── GetGasPriceProcedureTests.swift │ │ ├── GetTransactionsCountProcedureTests.swift │ │ ├── JSONResultStringTests.swift │ │ ├── SimpleProcedureTests.swift │ │ ├── TransactionReceiptProcedureTests.swift │ │ └── VerifiedProcedureTests.swift │ ├── RLP │ │ ├── EthRLPTests.swift │ │ └── RLPTests.swift │ ├── States │ │ └── StatesTests.swift │ ├── StringScalar │ │ ├── CompactHexStringTests.swift │ │ ├── HexPrefixTests.swift │ │ ├── HexPrefixedStringTests.swift │ │ ├── HexStringTests.swift │ │ ├── PrefixedHexStringTests.swift │ │ ├── PrefixedStringTests.swift │ │ ├── TrimmedPrefixStringTests.swift │ │ ├── UTF8StringTests.swift │ │ └── UnprefixedHexStringTests.swift │ ├── Transaction │ │ └── EthTransactionIT.swift │ ├── TransactionBytes │ │ ├── ContractDeploymentAndCallIT.swift │ │ ├── EthContractCallBytesTests.swift │ │ ├── EthContractCreationBytesTests.swift │ │ ├── EthDirectTransactionBytesTests.swift │ │ ├── EthManuallySignedTransactionBytesTests.swift │ │ ├── EthTransactionBytesTests.swift │ │ └── EthUnsignedTransactionBytesTests.swift │ ├── TransactionHash │ │ └── EthTransactionHashIT.swift │ ├── TransactionLog │ │ └── EthTransactionLogTests.swift │ ├── TransactionReceipt │ │ └── EthTransactionReceiptIT.swift │ └── Transactions │ │ └── EthTransactionsTests.swift ├── TransactionLogs │ └── MockedTransactionLogWithTransfer.swift ├── Web3Swift.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDETemplateMacros.plist │ │ └── xcschemes │ │ ├── All-Tests.xcscheme │ │ └── Web3Swift-Example.xcscheme ├── Web3Swift.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ ├── IDETemplateMacros.plist │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings └── Web3Swift │ ├── AppDelegate.swift │ ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift ├── LICENSE ├── README.md ├── Web3Swift.io.podspec ├── Web3Swift ├── ABI │ ├── Decoding │ │ ├── ABICollectionSlice.swift │ │ ├── ABIMessage.swift │ │ ├── DecodedABIAddress.swift │ │ ├── DecodedABIBoolean.swift │ │ ├── DecodedABIDynamicCollection.swift │ │ ├── DecodedABIFixedBytes.swift │ │ ├── DecodedABINumber.swift │ │ ├── DecodedABIString.swift │ │ └── DecodedABIVariableBytes.swift │ ├── EncodedABIFunction.swift │ ├── EncodedABITuple.swift │ ├── EncodedContract.swift │ └── Parameters │ │ ├── ABIAddress.swift │ │ ├── ABIBoolean.swift │ │ ├── ABIDynamicCollection.swift │ │ ├── ABIEncodedParameter.swift │ │ ├── ABIFixedBytes.swift │ │ ├── ABIString.swift │ │ ├── ABITuple.swift │ │ ├── ABITupleEncoding.swift │ │ ├── ABIUnsignedNumber.swift │ │ └── ABIVariableBytes.swift ├── Account │ ├── Account.swift │ └── EthAutoAccount.swift ├── Address │ ├── ComputedContractAddress.swift │ └── EthAddress.swift ├── Balance │ └── EthBalance.swift ├── Blockchain │ ├── BlockChainState.swift │ ├── EarliestBlockChainState.swift │ ├── ExactBlockChainState.swift │ ├── LatestBlockChainState.swift │ └── PendingBlockChainState.swift ├── Blocks │ ├── Block.swift │ ├── BlockHash.swift │ ├── EthBlock.swift │ └── EthBlockHash.swift ├── BooleanScalar │ ├── And.swift │ ├── BooleanScalar.swift │ ├── False.swift │ ├── NumericBoolean.swift │ ├── SimpleBoolean.swift │ ├── Ternary.swift │ └── True.swift ├── BytesScalar │ ├── ASCIIStringBytes.swift │ ├── BytesAt.swift │ ├── BytesFromCompactHexString.swift │ ├── BytesFromHexString.swift │ ├── BytesScalar.swift │ ├── CachedBytes.swift │ ├── ConcatenatedBytes.swift │ ├── EmptyBytes.swift │ ├── FirstBit.swift │ ├── FirstByte.swift │ ├── FirstBytes.swift │ ├── FixedLengthBytes.swift │ ├── IntegerBytes.swift │ ├── Keccak256Bytes.swift │ ├── LastBytes.swift │ ├── LeftPaddedBytes.swift │ ├── LeftZeroesPaddedBytes.swift │ ├── NumberHex.swift │ ├── ReversedBytes.swift │ ├── RightZeroesPaddedBytes.swift │ ├── SimpleBytes.swift │ ├── SizeBufferedBytes.swift │ ├── TrailingCompactBytes.swift │ ├── Trimmed255PrefixBytes.swift │ ├── TrimmedPrefixBytes.swift │ ├── TrimmedZeroPrefixBytes.swift │ └── UTF8StringBytes.swift ├── CollectionScalar │ ├── BytesAsCollection.swift │ ├── CachedCollection.swift │ ├── CollectionScalar.swift │ ├── CollectionSuffix.swift │ ├── ElementAt.swift │ ├── EnumeratedCollection.swift │ ├── GeneratedCollection.swift │ ├── MappedCollection.swift │ ├── SimpleCollection.swift │ ├── SizeConstrainedCollection.swift │ └── SizeOf.swift ├── ContractCall │ └── EthContractCall.swift ├── DecimalScalar │ ├── DecimalFromHex.swift │ ├── DecimalScalar.swift │ └── NormalizedDecimalFromHex.swift ├── Entropy │ ├── Entropy.swift │ └── RandomNonce.swift ├── Errors │ └── DescribedError.swift ├── Extensions │ ├── BigUInt.swift │ ├── Collection.swift │ ├── Data.swift │ ├── FixedWidthInteger.swift │ ├── Int.swift │ ├── JSON.swift │ ├── URLPostRequest.swift │ └── URLSession.swift ├── Functions │ └── StickyComputation.swift ├── GasEstimate │ └── EthGasEstimate.swift ├── GasPrice │ └── EthGasPrice.swift ├── IntegerScalar │ ├── BigEndianInteger.swift │ ├── BytesAsInteger.swift │ ├── CachedInteger.swift │ ├── EthInteger.swift │ ├── IntegerScalar.swift │ ├── IntegerTypeSize.swift │ ├── IntegersDifference.swift │ ├── IntegersEquality.swift │ ├── IntegersProduct.swift │ ├── IntegersQuotient.swift │ ├── IntegersSum.swift │ ├── IsNegativeEthInteger.swift │ ├── NaturalInteger.swift │ ├── RangeConstrainedInteger.swift │ ├── SimpleInteger.swift │ └── TernaryInteger.swift ├── Network │ ├── AlchemyNetwork.swift │ ├── EthNetwork.swift │ ├── GethNetwork.swift │ ├── InfuraNetwork.swift │ ├── Network.swift │ ├── NetworkID.swift │ ├── SimpleNetwork.swift │ └── VerifiedNetwork.swift ├── NumberScalar │ ├── ArithmeticFunctions.swift │ ├── EthNumber.swift │ ├── HexAsDecimalString.swift │ ├── UnsignedNumbersDifference.swift │ ├── UnsignedNumbersEquality.swift │ ├── UnsignedNumbersExponentiation.swift │ ├── UnsignedNumbersProduct.swift │ ├── UnsignedNumbersQuotient.swift │ ├── UnsignedNumbersSum.swift │ └── Zero.swift ├── Params │ ├── BooleanParameter.swift │ ├── BytesParameter.swift │ ├── EthParameter.swift │ ├── ObjectParameter.swift │ ├── QuantityParameter.swift │ └── TagParameter.swift ├── PersonalMessageBytes │ ├── PersonalMessageBytes.swift │ └── SignedPersonalMessageBytes.swift ├── PrivateKey │ ├── EthPrivateKey.swift │ ├── PrivateKey.swift │ └── PrivateKeyAddress.swift ├── RLP │ ├── EthRLP.swift │ ├── RLP.swift │ ├── RLPAppendix.swift │ ├── RLPBytesAppendix.swift │ ├── RLPCollectionsAppendix.swift │ ├── RLPStandardAppendix.swift │ └── SimpleRLP.swift ├── RemoteProcedure │ ├── BalanceProcedure.swift │ ├── BlockByHashProcedure.swift │ ├── CachedProcedure.swift │ ├── ChainIDProcedure.swift │ ├── ContractCallProcedure.swift │ ├── EstimateGasProcedure.swift │ ├── GetGasPriceProcedure.swift │ ├── GetTransactionsCountProcedure.swift │ ├── JSONResultString.swift │ ├── RemoteProcedure.swift │ ├── SendRawTransactionProcedure.swift │ ├── SimpleProcedure.swift │ ├── TransactionProcedure.swift │ ├── TransactionReceiptProcedure.swift │ └── VerifiedProcedure.swift ├── SECP256k1 │ ├── ECRecoverableSignature.swift │ └── SECP256k1Signature.swift ├── StringScalar │ ├── CompactHexString.swift │ ├── HexPrefix.swift │ ├── HexPrefixedString.swift │ ├── HexString.swift │ ├── PrefixedHexString.swift │ ├── PrefixedString.swift │ ├── SimpleString.swift │ ├── StringScalar.swift │ ├── TrimmedPrefixString.swift │ ├── UTF8String.swift │ └── UnprefixedHexString.swift ├── Transaction │ ├── EthTransaction.swift │ └── Transaction.swift ├── TransactionBytes │ ├── EthContractCallBytes.swift │ ├── EthContractCreationBytes.swift │ ├── EthDirectTransactionBytes.swift │ ├── EthManuallySignedTransactionBytes.swift │ ├── EthTransactionBytes.swift │ └── EthUnsignedTransactionBytes.swift ├── TransactionHash │ ├── EthTransactionHash.swift │ └── TransactionHash.swift ├── TransactionLogs │ ├── EthTransactionLog.swift │ └── TransactionLog.swift ├── TransactionReceipt │ ├── EthTransactionReceipt.swift │ └── TransactionReceipt.swift └── Transactions │ ├── EthTransactions.swift │ ├── Transactions.swift │ └── TransactionsCount.swift ├── _Pods.xcodeproj ├── buddybuild_postclone.sh ├── codecov.yml ├── package.json └── yarn.lock /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj merge=union -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # AppCode 2 | .idea/ 3 | 4 | # OS X 5 | .DS_Store 6 | 7 | # Xcode 8 | build/ 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata/ 18 | *.xccheckout 19 | profile 20 | *.moved-aside 21 | DerivedData 22 | *.hmap 23 | *.ipa 24 | 25 | # Bundler 26 | .bundle 27 | 28 | ## Other 29 | *.orig 30 | *.xccheckout 31 | *.moved-aside 32 | *.xcuserstate 33 | Pods/ 34 | node_modules/ 35 | yarn-error.log 36 | 37 | Carthage 38 | # We recommend against adding the Pods directory to your .gitignore. However 39 | # you should judge for yourself, the pros and cons are mentioned at: 40 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 41 | # 42 | # Note: if you ignore the Pods directory, make sure to uncomment 43 | # `pod install` in .travis.yml 44 | # 45 | # Pods/ 46 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 4.0 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * http://www.objc.io/issue-6/travis-ci.html 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode11.3 6 | language: objective-c 7 | # cache: cocoapods 8 | podfile: Example/Podfile 9 | cache: 10 | yarn: true 11 | cocoapods: true 12 | directories: 13 | - node_modules 14 | - $HOME/Library/Caches/Homebrew 15 | before_install: 16 | - gem install cocoapods 17 | - gem install xcpretty -N 18 | - pod repo update 19 | - pod install --project-directory=Example 20 | - brew install yarn 21 | - yarn install 22 | - yarn run ganache-cli 23 | --account="0x1636e10756e62baabddd4364010444205f1216bdb1644ff8f776f6e2982aa9f5,1000000000000000000" 24 | --account="0x159b7c413354adec1bd31caaf7e4fde71e9132a5b29193d2f6181de777745493,1000000000000000000" 25 | --account="0x4836d1e4785f62498ec6a7a61ff0d01e3fa97dba863a76f5a6c3ace47f62be3f,100000000000000000000" 26 | --gasPrice="20000000000" --networkId="1" & 27 | script: 28 | - pod lib lint --allow-warnings 29 | - set -o pipefail && xcodebuild clean test -enableCodeCoverage YES -workspace Example/Web3Swift.xcworkspace -scheme All-Tests -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 8,OS=11.3' ONLY_ACTIVE_ARCH=YES | xcpretty 30 | - bash <(curl -s https://codecov.io/bash) -t 475c7b5c-1657-4aa3-bd40-c699b20e518d -------------------------------------------------------------------------------- /Example/Actors/Actor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project. 3 | // Copyright 2018 The Web3Swift Authors. 4 | // Licensed under Apache License v2.0 5 | // 6 | // Actor.swift 7 | // 8 | // Created by Vadim Koleoshkin on 24/02/2018 9 | // 10 | 11 | import Foundation 12 | @testable import Web3Swift 13 | 14 | protocol Actor { 15 | 16 | func privateKey() -> PrivateKey 17 | 18 | func address() -> BytesScalar 19 | 20 | func rawAddress() -> String 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Example/Actors/Alice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project. 3 | // Copyright 2018 The Web3Swift Authors. 4 | // Licensed under Apache License v2.0 5 | // 6 | // Alice.swift 7 | // 8 | // Created by Vadim Koleoshkin on 24/02/2018 9 | // 10 | 11 | /// Female actor for testing 12 | import CryptoSwift 13 | import Foundation 14 | @testable import Web3Swift 15 | 16 | public final class Alice: Actor { 17 | 18 | private let origin = SimpleActor( 19 | privateKey: EthPrivateKey( 20 | bytes: BytesFromHexString( 21 | hex: "0x1636e10756e62baabddd4364010444205f1216bdb1644ff8f776f6e2982aa9f5" 22 | ) 23 | ) 24 | ) 25 | 26 | public func privateKey() -> PrivateKey { 27 | return origin.privateKey() 28 | } 29 | 30 | public func address() -> BytesScalar { 31 | return origin.address() 32 | } 33 | 34 | public func rawAddress() -> String { 35 | return origin.rawAddress() 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Example/Actors/Bob.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project. 3 | // Copyright 2018 The Web3Swift Authors. 4 | // Licensed under Apache License v2.0 5 | // 6 | // Bob.swift 7 | // 8 | // Created by Vadim Koleoshkin on 24/02/2018 9 | // 10 | 11 | /// Male actor for testing 12 | import Foundation 13 | @testable import Web3Swift 14 | 15 | public final class Bob: Actor { 16 | 17 | private let origin = SimpleActor( 18 | privateKey: EthPrivateKey( 19 | bytes: BytesFromHexString( 20 | hex: "0x159b7c413354adec1bd31caaf7e4fde71e9132a5b29193d2f6181de777745493" 21 | ) 22 | ) 23 | ) 24 | 25 | public func privateKey() -> PrivateKey { 26 | return origin.privateKey() 27 | } 28 | 29 | public func address() -> BytesScalar { 30 | return origin.address() 31 | } 32 | 33 | public func rawAddress() -> String { 34 | return origin.rawAddress() 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Example/Actors/SimpleActor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleActor.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | @testable import Web3Swift 13 | 14 | public final class SimpleActor: Actor { 15 | 16 | private let key: PrivateKey 17 | init(privateKey: PrivateKey) { 18 | self.key = privateKey 19 | } 20 | 21 | public func privateKey() -> PrivateKey { 22 | return key 23 | } 24 | 25 | public func address() -> BytesScalar { 26 | return try! privateKey().address() 27 | } 28 | 29 | public func rawAddress() -> String { 30 | return try! "0x\(privateKey().address().value().toHexString())" 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Example/Actors/Tim.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Tim.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | @testable import Web3Swift 13 | 14 | public final class Tim: Actor { 15 | 16 | private let origin = SimpleActor( 17 | privateKey: EthPrivateKey( 18 | bytes: BytesFromHexString( 19 | hex: "0x4836d1e4785f62498ec6a7a61ff0d01e3fa97dba863a76f5a6c3ace47f62be3f" 20 | ) 21 | ) 22 | ) 23 | 24 | public func privateKey() -> PrivateKey { 25 | return origin.privateKey() 26 | } 27 | 28 | public func address() -> BytesScalar { 29 | return origin.address() 30 | } 31 | 32 | public func rawAddress() -> String { 33 | return origin.rawAddress() 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Example/Errors/UnknownError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnknownError.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import Web3Swift 13 | 14 | public final class UnknownError: DescribedError { 15 | 16 | public var description: String { 17 | return "The error cause is unknown" 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Example/Extensions/URL.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // URL.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | fileprivate class InvalidURLStringError: Swift.Error { } 14 | 15 | extension URL { 16 | 17 | init(string: String) throws { 18 | if let url = (URL(string: string) as URL?) { 19 | self = url 20 | } else { 21 | throw InvalidURLStringError() 22 | } 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Example/Networks/GanacheLocalNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TestingEthereumNetwork.swift 7 | // 8 | // Created by Vadim Koleoshkin on 21/02/2018 9 | // 10 | 11 | import Foundation 12 | @testable import Web3Swift 13 | 14 | //Local test net 15 | public final class GanacheLocalNetwork: Network { 16 | 17 | private let origin: Network 18 | 19 | /** 20 | Ctor 21 | */ 22 | init() { 23 | origin = GethNetwork(url: "http://127.0.0.1:8545") 24 | } 25 | 26 | /** 27 | - returns: 28 | Id of a ganache network 29 | 30 | - throws: 31 | `DescribedError` if something went wrong 32 | */ 33 | public func id() throws -> IntegerScalar { 34 | return try origin.id() 35 | } 36 | 37 | /** 38 | - returns: 39 | `Data` from the testnet 40 | 41 | - throws: 42 | `DescribedError` if something went wrong 43 | */ 44 | public func call(method: String, params: Array) throws -> Data { 45 | return try origin.call(method: method, params: params) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Example/Networks/MainnetAlchemyNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // MainnetAlchemyNetwork.swift 7 | // 8 | // Created by Vadim Koleoshkin on 27/03/2019 9 | // 10 | 11 | import Foundation 12 | import Web3Swift 13 | 14 | // Ethereum mainnet via alchemyapi.io service and a Web3Swift.io api key 15 | // This is a demo key provided by Alchemy for testing purposes only and has lower performance. 16 | // Sign up for an official key at https://alchemyapi.io if you plan to use this in any development, staging, or production environments. 17 | public final class MainnetAlchemyNetwork: Network { 18 | 19 | private let origin: Network = AlchemyNetwork(chain: "mainnet", apiKey: "ETi2ntZoWxd6nTI1qE13Q4I1eLB8AMDl") 20 | 21 | /** 22 | - returns: 23 | Id of a mainnet (should be 1) 24 | 25 | - throws: 26 | `DescribedError` if something went wrong 27 | */ 28 | public func id() throws -> IntegerScalar { 29 | return try origin.id() 30 | } 31 | 32 | /** 33 | - returns: 34 | `Data` for a JSON RPC call to mainnet 35 | 36 | - throws: 37 | `DescribedError` if something went wrong 38 | */ 39 | public func call(method: String, params: Array) throws -> Data { 40 | return try origin.call( 41 | method: method, 42 | params: params 43 | ) 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Example/Networks/MainnetMetamaskNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // MainnetInfuraNetwork.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import Web3Swift 13 | 14 | //Ethereum mainnet via infura service and a Web3Swift.io api key 15 | public final class MainnetInfuraNetwork: Network { 16 | 17 | private let origin: Network = InfuraNetwork(chain: "mainnet", apiKey: "0c4d6dc730244b4185a6bde26f981bff") 18 | 19 | /** 20 | - returns: 21 | Id of a mainnet (should be 1) 22 | 23 | - throws: 24 | `DescribedError` if something went wrong 25 | */ 26 | public func id() throws -> IntegerScalar { 27 | return try origin.id() 28 | } 29 | 30 | /** 31 | - returns: 32 | `Data` for a JSON RPC call to mainnet 33 | 34 | - throws: 35 | `DescribedError` if something went wrong 36 | */ 37 | public func call(method: String, params: Array) throws -> Data { 38 | return try origin.call( 39 | method: method, 40 | params: params 41 | ) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '10.0' 2 | use_frameworks! 3 | 4 | target 'Web3Swift_Example' do 5 | pod 'Web3Swift.io', :path => '../' 6 | pod 'SwiftLint', '~> 0.27' 7 | end 8 | 9 | target 'Web3Swift_Tests' do 10 | pod 'Web3Swift.io', :path => '../' 11 | pod 'SwiftLint', '= 0.27' 12 | pod 'Quick', '~> 1.2' 13 | pod 'Nimble', '~> 7.0' 14 | end 15 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - BigInt (5.0.0) 3 | - CryptoSwift (1.3.1) 4 | - Nimble (7.3.4) 5 | - Quick (1.3.4) 6 | - secp256k1.swift (0.1.4) 7 | - SwiftLint (0.27.0) 8 | - SwiftyJSON (4.3.0) 9 | - Web3Swift.io (0.0.4): 10 | - BigInt (~> 5.0) 11 | - CryptoSwift (~> 1.0) 12 | - secp256k1.swift (~> 0.1) 13 | - SwiftyJSON (~> 4.3) 14 | 15 | DEPENDENCIES: 16 | - Nimble (~> 7.0) 17 | - Quick (~> 1.2) 18 | - SwiftLint (= 0.27) 19 | - SwiftLint (~> 0.27) 20 | - Web3Swift.io (from `../`) 21 | 22 | SPEC REPOS: 23 | trunk: 24 | - BigInt 25 | - CryptoSwift 26 | - Nimble 27 | - Quick 28 | - secp256k1.swift 29 | - SwiftLint 30 | - SwiftyJSON 31 | 32 | EXTERNAL SOURCES: 33 | Web3Swift.io: 34 | :path: "../" 35 | 36 | SPEC CHECKSUMS: 37 | BigInt: 74b4d88367b0e819d9f77393549226d36faeb0d8 38 | CryptoSwift: f12f037f6d0fcd6d48c96db0071b653de64e6c4d 39 | Nimble: 051e3d8912d40138fa5591c78594f95fb172af37 40 | Quick: f4f7f063c524394c73ed93ac70983c609805d481 41 | secp256k1.swift: a7e7a214f6db6ce5db32cc6b2b45e5c4dd633634 42 | SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073 43 | SwiftyJSON: 6faa0040f8b59dead0ee07436cbf76b73c08fd08 44 | Web3Swift.io: c10366f6daa98d6cd669d053fbe831b0ed20338d 45 | 46 | PODFILE CHECKSUM: a92dfff1059a074e829f137af158b15e15bc2d87 47 | 48 | COCOAPODS: 1.9.3 49 | -------------------------------------------------------------------------------- /Example/Tests/BooleanScalar/FalseTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // FalseTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class FalseTests: XCTestCase { 16 | 17 | func testFalsePersists() { 18 | expect{ 19 | try False().value() 20 | }.to( 21 | equal( 22 | false 23 | ), 24 | description: "False is expected to always be false" 25 | ) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Example/Tests/BooleanScalar/TernaryTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TernaryTests.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class TernaryTests: XCTestCase { 16 | 17 | func testTrueLeadsToThen() { 18 | expect{ 19 | try Ternary( 20 | if: SimpleBoolean( 21 | bool: true 22 | ), 23 | then: true, 24 | else: false 25 | ).value() 26 | }.to( 27 | equal( 28 | true 29 | ), 30 | description: "If boolean evaluates to true `then` statement is expected to be invoked" 31 | ) 32 | } 33 | 34 | func testFalseLeadsToElse() { 35 | expect{ 36 | try Ternary( 37 | if: SimpleBoolean( 38 | bool: false 39 | ), 40 | then: true, 41 | else: false 42 | ).value() 43 | }.to( 44 | equal( 45 | false 46 | ), 47 | description: "If boolean evaluates to false `else` statement is expected to be invoked" 48 | ) 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /Example/Tests/BooleanScalar/TrueTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TrueTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class TrueTests: XCTestCase { 16 | 17 | func testTruePersists() { 18 | expect{ 19 | try True().value() 20 | }.to( 21 | equal( 22 | true 23 | ), 24 | description: "True is expected to always be true" 25 | ) 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/ASCIIStringBytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ASCIIStringBytesTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import CryptoSwift 12 | import Nimble 13 | import Quick 14 | @testable import Web3Swift 15 | 16 | final class ASCIIStringBytesTests: XCTestCase { 17 | 18 | func testGivesCorrectASCIIRepresentation() { 19 | expect{ 20 | try ASCIIStringBytes( 21 | string: SimpleString( 22 | string: "hello" 23 | ) 24 | ).value() 25 | }.to( 26 | equal( 27 | Data( 28 | hex: "68656c6c6f" 29 | ) 30 | ), 31 | description: "ascii representation is expected to persist" 32 | ) 33 | } 34 | 35 | func testNonASCIICharacterThrows() { 36 | expect{ 37 | try ASCIIStringBytes( 38 | string: SimpleString( 39 | string: "∆" 40 | ) 41 | ).value() 42 | }.to( 43 | throwError(errorType: NotAnASCIIScalarError.self), 44 | description: "Non ascii characters are expected to cause an error" 45 | ) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/BytesAsCollectionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BytesAsCollectionTests.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class BytesAsCollectionTests: XCTestCase { 16 | 17 | func testBytesArePersisted() { 18 | let bytes: [UInt8] = [0x01, 0x02, 0x03, 0x42] 19 | expect{ 20 | try BytesAsCollection( 21 | origin: SimpleBytes( 22 | bytes: bytes 23 | ) 24 | ).value() 25 | }.to( 26 | equal( 27 | bytes 28 | ), 29 | description: "Bytes are expected to persist" 30 | ) 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/FirstByteTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // FirstByteTests.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class FirstByteTests: XCTestCase { 16 | 17 | func testFirstByteIsTakenCorrectly() { 18 | expect{ 19 | try FirstByte( 20 | origin: SimpleBytes( 21 | bytes: [42, 43] 22 | ) 23 | ).value() 24 | }.to( 25 | equal( 26 | 42 27 | ), 28 | description: "Correct first byte is expected" 29 | ) 30 | } 31 | 32 | func testEmptyBytesThrow() { 33 | expect{ 34 | try FirstByte( 35 | origin: SimpleBytes( 36 | bytes: [] 37 | ) 38 | ).value() 39 | }.to( 40 | throwError( 41 | errorType: IndexOutOfBoundsError.self 42 | ), 43 | description: "Empty collection is expected to throw" 44 | ) 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/FirstBytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // FirstBytesTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class FirstBytesTests: XCTestCase { 16 | 17 | func testTakesFirstBytesCorrectlyWhenSufficient() { 18 | expect{ 19 | try FirstBytes( 20 | origin: SimpleBytes( 21 | bytes: [ 22 | 0x01, 0x02, 0x03, 0x04, 0x05 23 | ] 24 | ), 25 | length: 3 26 | ).value() 27 | }.to( 28 | equal( 29 | Data( 30 | [ 31 | 0x01, 0x02, 0x03 32 | ] 33 | ) 34 | ) 35 | ) 36 | } 37 | 38 | func testTakesFirstBytesCorrectlyWhenInsufficient() { 39 | expect{ 40 | try FirstBytes( 41 | origin: SimpleBytes( 42 | bytes: [ 43 | 0x01, 0x02 44 | ] 45 | ), 46 | length: 3 47 | ).value() 48 | }.to( 49 | equal( 50 | Data( 51 | [ 52 | 0x01, 0x02 53 | ] 54 | ) 55 | ) 56 | ) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/IntegerBytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // IntegerBytesTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class IntegerBytesTests: XCTestCase { 16 | 17 | func testMemory() { 18 | expect{ 19 | MemoryLayout.size 20 | }.to( 21 | equal(8) 22 | ) 23 | } 24 | 25 | func testLittleEndianInteger() { 26 | expect{ 27 | try IntegerBytes( 28 | value: Int(1).littleEndian 29 | ).value() 30 | }.to( 31 | equal( 32 | Data( 33 | [0x01] + Array(repeating: 0x00, count: MemoryLayout.size - 1) 34 | ) 35 | ), 36 | description: "Integer bytes are expected to respect endianness" 37 | ) 38 | } 39 | 40 | func testBigEndianInteger() { 41 | expect{ 42 | try IntegerBytes( 43 | value: Int(1).bigEndian 44 | ).value() 45 | }.to( 46 | equal( 47 | Data( 48 | Array(repeating: 0x00, count: MemoryLayout.size - 1) + [0x01] 49 | ) 50 | 51 | ), 52 | description: "Integer bytes are expected to respect endianness" 53 | ) 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/Keccak256BytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Keccak256BytesTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import CryptoSwift 12 | import Nimble 13 | import Quick 14 | @testable import Web3Swift 15 | 16 | final class Keccak256BytesTests: XCTestCase { 17 | 18 | func testDigestsCorrectly() { 19 | expect{ 20 | try Keccak256Bytes( 21 | origin: ASCIIStringBytes( 22 | string: SimpleString( 23 | string: "baz(uint32,bool)" 24 | ) 25 | ) 26 | ).value() 27 | }.to( 28 | equal( 29 | Data( 30 | hex: "cdcd77c0992ec5bbfc459984220f8c45084cc24d9b6efed1fae540db8de801d2" 31 | ) 32 | ), 33 | description: "Keccak256 is expected to digest correctly" 34 | ) 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/LastBytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // LastBytesTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class LastBytesTests: XCTestCase { 16 | 17 | func testTakesLastBytesCorrectlyWhenSufficient() { 18 | expect{ 19 | try LastBytes( 20 | origin: SimpleBytes( 21 | bytes: [ 22 | 0x01, 0x02, 0x03, 0x04, 0x05 23 | ] 24 | ), 25 | length: 3 26 | ).value() 27 | }.to( 28 | equal( 29 | Data( 30 | [ 31 | 0x03, 0x04, 0x05 32 | ] 33 | ) 34 | ) 35 | ) 36 | } 37 | 38 | func testTakesLastBytesCorrectlyWhenInsufficient() { 39 | expect{ 40 | try LastBytes( 41 | origin: SimpleBytes( 42 | bytes: [ 43 | 0x01, 0x02 44 | ] 45 | ), 46 | length: 3 47 | ).value() 48 | }.to( 49 | equal( 50 | Data( 51 | [ 52 | 0x01, 0x02 53 | ] 54 | ) 55 | ) 56 | ) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/ReversedBytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ReversedBytesTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import CryptoSwift 12 | import Nimble 13 | import Quick 14 | @testable import Web3Swift 15 | 16 | final class ReversedBytesTests: XCTestCase { 17 | 18 | func testBytesAreCorrectlyReversed() { 19 | expect{ 20 | try ReversedBytes( 21 | origin: SimpleBytes( 22 | bytes: [ 23 | 1, 2, 3, 4 24 | ] 25 | ) 26 | ).value() 27 | }.to( 28 | equal( 29 | Data( 30 | [ 31 | 4, 3, 2, 1 32 | ] 33 | ) 34 | ), 35 | description: "Bytes are expected to be correctly reversed" 36 | ) 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Example/Tests/BytesScalar/UTF8StringBytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UTF8StringBytesTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class UTF8StringBytesTests: XCTestCase { 16 | 17 | func testCorrectUTF8Bytes() { 18 | expect{ 19 | try UTF8StringBytes( 20 | string: "Hello world" 21 | ).value() 22 | }.to( 23 | equal( 24 | Data( 25 | Array("Hello world".utf8) 26 | ) 27 | ) 28 | ) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Example/Tests/Collection/CollectionSingleTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CollectionSingleTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class CollectionSingleTests: XCTestCase { 16 | 17 | func testCorrectSingleCollections() { 18 | expect{ 19 | try "d".single() 20 | }.toNot( 21 | throwError(), 22 | description: "Single of a collection is not expected to throw error when 1 element is present" 23 | ) 24 | } 25 | 26 | func testBigSingleCollections() { 27 | expect{ 28 | try "da".single() 29 | }.to( 30 | throwError(errorType: IncorrectNumberOfElementsError.self), 31 | description: "Single of a collection is expected to throw when more than 1 element is present" 32 | ) 33 | } 34 | 35 | func testEmptySingleCollections() { 36 | expect{ 37 | try "".single() 38 | }.to( 39 | throwError(errorType: IncorrectNumberOfElementsError.self), 40 | description: "Single of a collection is expected to throw when more than 0 element is present" 41 | ) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Example/Tests/CollectionScalar/ElementAtTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ElementAtTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class ElementAtTests: XCTestCase { 16 | 17 | func testCorrectElementIsFetched() { 18 | expect{ 19 | try ElementAt( 20 | collection: SimpleCollection( 21 | collection: [ 22 | 0, 1, 2, 3, 4 23 | ] 24 | ), 25 | index: 3 26 | ).value() 27 | }.to( 28 | equal(3), 29 | description: "Element at an index is expected to fetch the same element as a standard array subscript" 30 | ) 31 | } 32 | 33 | func testUnderflowThrows() { 34 | expect{ 35 | try ElementAt( 36 | collection: SimpleCollection( 37 | collection: [ 38 | 0, 1, 2, 3, 4 39 | ] 40 | ), 41 | index: 5 42 | ).value() 43 | }.to( 44 | throwError(errorType: IndexOutOfBoundsError.self), 45 | description: "Element at an out of bounds index is expected to throw" 46 | ) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Example/Tests/CollectionScalar/EnumeratedCollectionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EnumeratedCollectionTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class EnumeratedCollectionTests: XCTestCase { 16 | 17 | func testElementsAreEnumeratedCorrectly() { 18 | let indexes: [Int] = [0, 1, 2, 3, 4, 5] 19 | expect{ 20 | try EnumeratedCollection( 21 | origin: SimpleCollection( 22 | collection: indexes 23 | ) 24 | ).value().map{ index, _ in 25 | index 26 | } 27 | }.to( 28 | equal( 29 | indexes 30 | ), 31 | description: "A collection is expected to be enumerated correctly" 32 | ) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Example/Tests/CollectionScalar/GeneratedCollectionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // GeneratedCollectionTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class GeneratedCollectionTests: XCTestCase { 16 | 17 | func testCorrectElementsAreEnumeratedAndGenerated() { 18 | expect{ 19 | try GeneratedCollection( 20 | element: { index in 21 | return index 22 | }, 23 | times: 5 24 | ).value() 25 | }.to( 26 | equal( 27 | [0, 1, 2, 3, 4] 28 | ), 29 | description: "Generated collection is expected to be called specified number of times with incremental indexes" 30 | ) 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Example/Tests/CollectionScalar/MappedCollectionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // MappedCollectionTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class MappedCollectionTests: XCTestCase { 16 | 17 | func testElementsAreMappedCorrectly() { 18 | expect{ 19 | try MappedCollection( 20 | origin: GeneratedCollection( 21 | element: { index in index }, 22 | times: 4 23 | ), 24 | mapping: { index in 25 | String( 26 | index + 1 27 | ) 28 | } 29 | ).value() 30 | }.to( 31 | equal( 32 | [ 33 | "1", 34 | "2", 35 | "3", 36 | "4" 37 | ] 38 | ) 39 | ) 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Example/Tests/CollectionScalar/SizeOfTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SizeOfTests.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class SizeOfTests: XCTestCase { 16 | 17 | func testSizeIsTakenCorrectly() { 18 | expect{ 19 | try SizeOf( 20 | collection: SimpleCollection( 21 | collection: Array( 22 | repeating: 0, 23 | count: 6 24 | ) 25 | ) 26 | ).value() 27 | }.to( 28 | equal( 29 | 6 30 | ), 31 | description: "Number of elements in the collection is expected to be counted correctly" 32 | ) 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /Example/Tests/DecimalScalar/NormalizedDecimalFromHexTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // NormalizedDecimalFromHexTests.swift 7 | // 8 | // Created by Vadim Koleoshkin on 10/05/2019 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | class NormalizedDecimalFromHexTests: XCTestCase { 16 | 17 | func testUInt256MaxConvertsToAValidDecimal() { 18 | expect{ 19 | try NormalizedDecimalFromHex( 20 | hex: EthNumber( 21 | hex: SimpleBytes( 22 | bytes: Array( 23 | repeating: 0xff, 24 | count: 32 25 | ) 26 | ) 27 | ), 28 | power: 27 // Maker PETH precision 29 | ).value() 30 | }.to( 31 | // swiftlint:disable force_unwrapping 32 | equal( 33 | Decimal(string: "115792089237316195423570985008687907853269984665640.564039457584007913129639935")! 34 | ), 35 | description: "Max UInt256 with precision 27 should expected to be encoded correctly" 36 | // swiftlint:enable force_unwrapping 37 | ) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Example/Tests/GasEstimate/EthGasEstimateTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthGasEstimateTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | import SwiftyJSON 14 | @testable import Web3Swift 15 | 16 | final class EthGasEstimateTests: XCTestCase { 17 | 18 | func testGasEstimateIsNonNegative() { 19 | let network = GanacheLocalNetwork() 20 | expect{ 21 | try EthInteger( 22 | hex: EthGasEstimate( 23 | network: network, 24 | senderAddress: EthAddress( 25 | hex: "0xcD8aC90d9cc7e4c03430d58d2f3e87Dae70b807e" 26 | ), 27 | recipientAddress: EthAddress( 28 | hex: "0x79d2c50Ba0cA4a2C6F8D65eBa1358bEfc1cFD403" 29 | ), 30 | gasPrice: EthGasPrice( 31 | network: network 32 | ), 33 | weiAmount: EthNumber( 34 | value: 100 35 | ) 36 | ) 37 | ).value() 38 | }.to( 39 | beGreaterThanOrEqualTo(0), 40 | description: "Network gas estimate is expected to be non negative number" 41 | ) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Example/Tests/GasPrice/EthGasPriceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthGasPriceTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class EthGasPriceTests: XCTestCase { 16 | 17 | func testNonNegativeGasPrice() { 18 | expect{ 19 | try EthInteger( 20 | hex: EthGasPrice( 21 | network: GanacheLocalNetwork() 22 | ) 23 | ).value() 24 | }.to( 25 | beGreaterThanOrEqualTo(0), 26 | description: "Value of an gas price reported by network is expected to be non negative" 27 | ) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/IntegerScalar/BigEndianIntegerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BigEndianIntegerTests.swift 7 | // 8 | // Created by Timofey Solonin on 22/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class BigEndianIntegerTests: XCTestCase { 16 | 17 | func testBigEndianRepresentationIsCorrect() { 18 | expect{ 19 | try UnprefixedHexString( 20 | bytes: TrimmedZeroPrefixBytes( 21 | origin: IntegerBytes( 22 | value: BigEndianInteger( 23 | origin: SimpleInteger( 24 | integer: 255 25 | ) 26 | ) 27 | ) 28 | ) 29 | ).value() 30 | }.to( 31 | equal( 32 | "ff" 33 | ) 34 | ) 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /Example/Tests/IntegerScalar/IntegerTypeSizeTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // IntegerTypeSizeTests.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class IntegerTypeSizeTests: XCTestCase { 16 | 17 | func testIntegerTypeSizeIsItsWidthInBytes() { 18 | expect{ 19 | try IntegerTypeSize().value() 20 | }.to( 21 | equal( 22 | MemoryLayout.size 23 | ), 24 | description: "Integer type size is Int type size in bytes" 25 | ) 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /Example/Tests/Network/MainnetInfuraMetamaskNetworkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // MainnetInfuraMetamaskNetworkTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | import SwiftyJSON 14 | @testable import Web3Swift 15 | 16 | final class MainnetInfuraMetamaskNetworkTests: XCTestCase { 17 | 18 | func testMainnetID() { 19 | expect{ 20 | try MainnetInfuraNetwork().id().value() 21 | }.to( 22 | equal(1), 23 | description: "Mainnet is expected to have an id of 1" 24 | ) 25 | } 26 | 27 | func testMainnetCall() { 28 | expect{ 29 | try JSON( 30 | data: MainnetInfuraNetwork().call( 31 | method: "net_version", 32 | params: [] 33 | ) 34 | )["result"].string() 35 | }.to( 36 | equal("1"), 37 | description: "net_version call on the mainnet is expected to return decimal string representation of a decimal number" 38 | ) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Example/Tests/Other/DataToDecimalTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DataToDecimalTests.swift 7 | // 8 | // Created by Vadim Koleoshkin on 11/05/2019 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | class DataToDecimalTests: XCTestCase { 16 | 17 | func testToDecimal() { 18 | expect{ 19 | try EthNumber(value: 256).value().toDecimal() 20 | }.to( 21 | equal(Decimal(256)), 22 | description: "Data expected to be converted correctly" 23 | ) 24 | } 25 | 26 | func testToNormalizedDecimal() { 27 | expect{ 28 | try EthNumber( 29 | value: 256 30 | ).value().toNormalizedDecimal( 31 | power: 2 32 | ) 33 | }.to( 34 | equal(Decimal(2.56)), 35 | description: "Data expected to be converted correctly" 36 | ) 37 | } 38 | 39 | func testToDecimalString() { 40 | expect{ 41 | try EthNumber( 42 | value: 256 43 | ).value().toDecimalString() 44 | }.to( 45 | equal("256"), 46 | description: "Data expected to be converted correctly" 47 | ) 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Example/Tests/Other/DataToHexTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DataToHexTests.swift 7 | // 8 | // Created by Vadim Koleoshkin on 11/05/2019 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | class DataToHexTests: XCTestCase { 16 | 17 | func testToHex() { 18 | expect{ 19 | try EthNumber(value: 256).value().toHexString() 20 | }.to( 21 | equal("0100"), 22 | description: "Data expected to be converted to hex correctly" 23 | ) 24 | } 25 | 26 | func testToPrefixedHex() { 27 | expect{ 28 | try EthNumber(value: 256).value().toPrefixedHexString() 29 | }.to( 30 | equal("0x0100"), 31 | description: "Data expected to be converted to prefixed hex correctly" 32 | ) 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Example/Tests/Params/QuantityParameterTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project. 3 | // Copyright 2018 The Web3Swift Authors. 4 | // Licensed under Apache License v2.0 5 | // 6 | // QuantityParameterTests.swift 7 | // 8 | // Created by Vadim Koleoshkin on 21/02/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | import XCTest 15 | 16 | class QuantityParameterTests: XCTestCase { 17 | 18 | /// Assert parameter returns correct hex string 19 | func testQuantityParameterToString() { 20 | expect{ 21 | try QuantityParameter( 22 | number: EthNumber( 23 | value: 1 24 | ) 25 | ).value() as? String 26 | }.to( 27 | equal("0x1"), 28 | description: "Make sure that correct hex string is returned" 29 | ) 30 | } 31 | 32 | func testZeroIsEncodedCorrectly() { 33 | expect{ 34 | try QuantityParameter( 35 | number: EthNumber( 36 | value: 0 37 | ) 38 | ).value() as? String 39 | }.to( 40 | equal( 41 | "0x0" 42 | ), 43 | description: "Zero is expected to represented correctly" 44 | ) 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Example/Tests/PrivateKey/PrivateKeyAddressTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // PrivateKeyAddressTests.swift 7 | // 8 | // Created by Timofey Solonin on 12/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class PrivateKeyAddressTests: XCTestCase { 16 | 17 | func testACorrectAddressIsReceivedFromPrivateKey() { 18 | expect{ 19 | try PrefixedHexString( 20 | bytes: PrivateKeyAddress( 21 | key: EthPrivateKey( 22 | bytes: BytesFromHexString( 23 | hex: "0x1636e10756e62baabddd4364010444205f1216bdb1644ff8f776f6e2982aa9f5" 24 | ) 25 | ) 26 | ) 27 | ).value() 28 | }.to( 29 | equal( 30 | "0xcd8ac90d9cc7e4c03430d58d2f3e87dae70b807e" 31 | ), 32 | description: "Private key address is expected to persist" 33 | ) 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /Example/Tests/Procedures/CachedProcedureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CachedProcedureTests.swift 7 | // 8 | // Created by Vadim Koleoshkin on 23/05/2019 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | import SwiftyJSON 14 | @testable import Web3Swift 15 | 16 | class CachedProcedureTests: XCTestCase { 17 | 18 | func testCachedProcedure() { 19 | let json = JSON( 20 | [ 21 | "Good times bad times" : "Bad times good times" 22 | ] 23 | ) 24 | expect{ 25 | try CachedProcedure( 26 | origin: SimpleProcedure( 27 | json: json 28 | ) 29 | ).call() 30 | }.to( 31 | equal(json), 32 | description: "Json is expected to persist" 33 | ) 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Example/Tests/Procedures/ChainIDProcedureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ChainIDProcedureTests.swift 7 | // 8 | // Created by Timofey Solonin on 2/1/18. 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | import XCTest 15 | 16 | final class ChainIDProcedureTests: XCTestCase { 17 | 18 | // Assert network does not throw an error on network call 19 | func testNoThrow() { 20 | expect( 21 | try ChainIDProcedure( 22 | network: MainnetInfuraNetwork() 23 | ).call() 24 | ).toNot( 25 | throwError(), 26 | description: "Make sure nework call does not throw an error" 27 | ) 28 | } 29 | 30 | /// Assert response contains right chain id 31 | func testMainNetID() { 32 | expect{ 33 | try ChainIDProcedure( 34 | network: MainnetInfuraNetwork() 35 | ).call()["result"].string() 36 | }.to( 37 | equal( 38 | "1" 39 | ), 40 | description: "Make sure right chain id is returned" 41 | ) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Example/Tests/Procedures/ContractCallProcedureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ContractCallProcedureTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class ContractCallProcedureTests: XCTestCase { 16 | 17 | func testEOSSupply() { 18 | expect{ 19 | try ContractCallProcedure( 20 | network: MainnetInfuraNetwork(), 21 | parameters: [ 22 | "to" : BytesParameter( 23 | bytes: EthAddress( 24 | hex: "0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0" 25 | ) 26 | ), 27 | "data" : BytesParameter( 28 | bytes: EncodedABIFunction( 29 | signature: SimpleString( 30 | string: "totalSupply()" 31 | ), 32 | parameters: [] 33 | ) 34 | ) 35 | ] 36 | ).call()["result"].string() 37 | }.to( 38 | equal( 39 | "0x0000000000000000000000000000000000000000033b2e3c9fd0803ce8000000" 40 | ), 41 | description: "EOS supply is expected to be 1,000,000,000 represented in abi encoded hex number" 42 | ) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Example/Tests/Procedures/GetGasPriceProcedureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // GetGasPriceProcedureTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | import XCTest 15 | 16 | final class GetGasPriceProcedureTests: XCTestCase { 17 | 18 | /// Assert network call returns non empty data 19 | func testNotEmptyData() { 20 | expect{ 21 | try GetGasPriceProcedure( 22 | network: MainnetInfuraNetwork() 23 | ).call() 24 | }.toNot( 25 | beEmpty() 26 | ) 27 | } 28 | 29 | /// Assert gas price should be number (in hex format) that is greater than 0 30 | func testValueGreaterThanZero() { 31 | expect{ 32 | try EthInteger( 33 | hex: GetGasPriceProcedure( 34 | network: MainnetInfuraNetwork() 35 | ).call()["result"].string() 36 | ).value() 37 | }.to( 38 | beGreaterThan(0), 39 | description: "Make sure positive gas price is returned" 40 | ) 41 | } 42 | 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /Example/Tests/Procedures/SimpleProcedureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleProcedureTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | import SwiftyJSON 14 | @testable import Web3Swift 15 | 16 | final class SimpleProcedureTests: XCTestCase { 17 | 18 | func testJsonIsPersisted() { 19 | let json = JSON( 20 | [ 21 | "hello" : "world" 22 | ] 23 | ) 24 | expect{ 25 | try SimpleProcedure( 26 | json: json 27 | ).call() 28 | }.to( 29 | equal(json), 30 | description: "Json is expected to persist" 31 | ) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Example/Tests/Procedures/TransactionReceiptProcedureTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TransactionReceiptProcedureTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | import SwiftyJSON 14 | @testable import Web3Swift 15 | 16 | final class TransactionReceiptProcedureTests: XCTestCase { 17 | 18 | func testNotEmptyReceipt() { 19 | expect{ 20 | try TransactionReceiptProcedure( 21 | network: MainnetInfuraNetwork(), 22 | transactionHash: BytesFromHexString( 23 | hex: "0xd84b4a8661d546b3858d5b6fcf5a815e5efab48786deee67a4441d27b22e3011" 24 | ) 25 | ).call()["result"].type 26 | }.to( 27 | equal(.dictionary), 28 | description: "This transaction from etherscan is expected to not be empty" 29 | ) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Example/Tests/StringScalar/HexPrefixTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // HexPrefixTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class HexPrefixTests: XCTestCase { 16 | 17 | func testCorrectValue() { 18 | expect{ 19 | try HexPrefix().value() 20 | }.to( 21 | equal("0x"), 22 | description: "Hex prefix is expected to be 0x" 23 | ) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Example/Tests/StringScalar/UTF8StringTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UTF8StringTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | final class UTF8StringTests: XCTestCase { 16 | 17 | func testNonUTF8BytesThrow() { 18 | expect{ 19 | try UTF8String( 20 | bytes: SimpleBytes( 21 | bytes: [ 22 | 0xc0 23 | ] 24 | ) 25 | ).value() 26 | }.to( 27 | throwError(errorType: NotUTF8BytesError.self), 28 | description: "Bytes that do not represent a valid utf8 string are expected to throw" 29 | ) 30 | } 31 | 32 | func testValidUTF8BytesProduceAString() { 33 | expect{ 34 | try UTF8String( 35 | bytes: UTF8StringBytes( 36 | string: "κόσμε" 37 | ) 38 | ).value() 39 | }.to( 40 | equal( 41 | "κόσμε" 42 | ), 43 | description: "Valid utf8 string is expected to be correctly constructed from its bytes" 44 | ) 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Example/Tests/TransactionBytes/EthUnsignedTransactionBytesTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthUnsignedTransactionBytesTests.swift 7 | // 8 | // Created by Vadim Koleoshkin on 24/07/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | 15 | class EthUnsignedTransactionBytesTests: XCTestCase { 16 | 17 | func testStaticParametersEncodedCorrectly() { 18 | expect{ 19 | return try EthUnsignedTransactionBytes( 20 | networkID: SimpleInteger( 21 | integer: 1 22 | ), 23 | transactionsCount: EthNumber( 24 | value: 128 25 | ), 26 | gasPrice: EthNumber( 27 | hex: "0x04A817C800" 28 | ), 29 | gasEstimate: EthNumber( 30 | value: 21000 31 | ), 32 | recipientAddress: Alice().address(), 33 | weiAmount: EthNumber( 34 | hex: "0x01" 35 | ), 36 | contractCall: EmptyBytes() 37 | ).value().toHexString() 38 | }.to( 39 | equal( 40 | "e581808504a817c80082520894cd8ac90d9cc7e4c03430d58d2f3e87dae70b807e0180018080" 41 | ), 42 | description: "Transaction parameters expected to encoded correctly" 43 | ) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/Tests/Transactions/EthTransactionsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthTransactionsTests.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Nimble 12 | import Quick 13 | @testable import Web3Swift 14 | import XCTest 15 | 16 | final class EthTransactionsTests: XCTestCase { 17 | 18 | /// Assert that transaction count returns positive number 19 | func testTransactionsCount() { 20 | expect{ 21 | try EthInteger( 22 | hex: EthTransactions( 23 | network: GanacheLocalNetwork(), 24 | address: Alice().address(), 25 | blockChainState: PendingBlockChainState() 26 | ).count() 27 | ).value() 28 | }.to( 29 | beGreaterThanOrEqualTo(0), 30 | description: "Make sure positive number is returned" 31 | ) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Example/Web3Swift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Web3Swift.xcodeproj/xcshareddata/IDETemplateMacros.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FILEHEADER 6 | 7 | // This source file is part of the Web3Swift.io open source project 8 | // Copyright ___YEAR___ The Web3Swift Authors 9 | // Licensed under Apache License v2.0 10 | // 11 | // ___FILENAME___ 12 | // 13 | // Created by ___FULLUSERNAME___ on ___DATE___ 14 | // 15 | 16 | 17 | -------------------------------------------------------------------------------- /Example/Web3Swift.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/Web3Swift.xcworkspace/xcshareddata/IDETemplateMacros.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | FILEHEADER 6 | 7 | // This source file is part of the Web3Swift.io open source project 8 | // Copyright ___YEAR___ The Web3Swift Authors 9 | // Licensed under Apache License v2.0 10 | // 11 | // ___FILENAME___ 12 | // 13 | // Created by ___FULLUSERNAME___ on ___DATE___ 14 | // 15 | 16 | 17 | -------------------------------------------------------------------------------- /Example/Web3Swift.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/Web3Swift.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/Web3Swift/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // AppDelegate.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import UIKit 12 | 13 | @UIApplicationMain 14 | class AppDelegate: UIResponder, UIApplicationDelegate { 15 | 16 | var window: UIWindow? 17 | 18 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 19 | fatalError("Example iOS usage is not implemented yet") 20 | } 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Example/Web3Swift/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/Web3Swift/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Example/Web3Swift/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ViewController.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import UIKit 12 | 13 | class ViewController: UIViewController { 14 | 15 | override func viewDidLoad() { 16 | super.viewDidLoad() 17 | // Do any additional setup after loading the view, typically from a nib. 18 | } 19 | 20 | override func didReceiveMemoryWarning() { 21 | super.didReceiveMemoryWarning() 22 | // Dispose of any resources that can be recreated. 23 | } 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /Web3Swift.io.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Web3Swift.io' 3 | s.version = '0.0.4' 4 | s.summary = 'Web3 library for Swift. Construct and sign transactions, interact with smart contracts.' 5 | 6 | s.description = <<-DESC 7 | Ethereum client library written in pure Swift. 8 | Sign transactions and messages, interact with smart contracts, 9 | encode and decode ABI messages. 10 | DESC 11 | 12 | s.homepage = 'https://github.com/zeriontech/Web3Swift' 13 | s.license = { :type => 'Apache License 2.0', :file => 'LICENSE' } 14 | s.author = { 15 | 'Timofey Solonin' => 'abdulowork@gmail.com', 16 | 'Vadim Koleoshkin' => 'vadim@koleoshkin.com' 17 | } 18 | s.source = { :git => 'https://github.com/zeriontech/Web3Swift.git', :tag => s.version.to_s } 19 | s.homepage = 'https://web3swift.io' 20 | 21 | s.ios.deployment_target = '10.0' 22 | s.osx.deployment_target = '10.14' 23 | 24 | s.module_name = 'Web3Swift' 25 | s.source_files = 'Web3Swift/**/*' 26 | s.dependency 'SwiftyJSON', '~> 4.3' 27 | s.dependency 'secp256k1.swift', '~> 0.1' 28 | s.dependency 'CryptoSwift', '~> 1.0' 29 | s.dependency 'BigInt', '~> 5.0' 30 | 31 | end 32 | -------------------------------------------------------------------------------- /Web3Swift/ABI/Decoding/DecodedABIAddress.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DecodedABIAddress.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Ethereum address decoded from an abi message */ 14 | public final class DecodedABIAddress: BytesScalar { 15 | 16 | private let origin: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - abiMessage: message where address is located 23 | - index: position of the address 24 | */ 25 | public init( 26 | abiMessage: CollectionScalar, 27 | index: Int 28 | ) { 29 | self.origin = EthAddress( 30 | bytes: NumberHex( 31 | number: DecodedABINumber( 32 | abiMessage: abiMessage, 33 | index: index 34 | ) 35 | ) 36 | ) 37 | } 38 | 39 | /** 40 | - returns: 41 | Address decoded from the message 42 | 43 | - throws: 44 | `DescribedError` if something 45 | */ 46 | public func value() throws -> Data { 47 | return try origin.value() 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Web3Swift/ABI/Decoding/DecodedABIBoolean.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DecodedABIBoolean.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Boolean decoded from an abi message */ 14 | public final class DecodedABIBoolean: BooleanScalar { 15 | 16 | private let origin: BooleanScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - abiMessage: message where boolean is located 23 | - index: position of the boolean 24 | */ 25 | public init( 26 | abiMessage: CollectionScalar, 27 | index: Int 28 | ) { 29 | self.origin = NumericBoolean( 30 | bool: DecodedABINumber( 31 | abiMessage: abiMessage, 32 | index: index 33 | ) 34 | ) 35 | } 36 | 37 | /** 38 | - returns: 39 | Boolean decoded from the message 40 | 41 | - throws: 42 | `DescribedError` if something went wrong. I.e. if value at the specified index did not represent a boolean 43 | */ 44 | public func value() throws -> Bool { 45 | return try origin.value() 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Web3Swift/ABI/Decoding/DecodedABIFixedBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DecodedABIFixedBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Decoded bytes with fixed length (up to 32) */ 14 | public final class DecodedABIFixedBytes: BytesScalar { 15 | 16 | private let bytes: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - abiMessage: message where bytes are located 23 | - length: expected number of bytes 24 | - index: position of the bytes 25 | */ 26 | public init( 27 | abiMessage: CollectionScalar, 28 | length: Int, 29 | index: Int 30 | ) { 31 | self.bytes = FirstBytes( 32 | origin: BytesAt( 33 | collection: abiMessage, 34 | index: index 35 | ), 36 | length: length 37 | ) 38 | } 39 | 40 | /** 41 | - returns: 42 | Decoded bytes 43 | 44 | - throws: 45 | `DescribedError` if something went wrong 46 | */ 47 | public func value() throws -> Data { 48 | return try bytes.value() 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/ABI/Decoding/DecodedABINumber.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DecodedABINumber.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Decoded number */ 14 | public final class DecodedABINumber: BytesScalar { 15 | 16 | private let number: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - abiMessage: message where number is located 23 | - index: position of the number 24 | */ 25 | public init( 26 | abiMessage: CollectionScalar, 27 | index: Int 28 | ) { 29 | self.number = EthNumber( 30 | hex: BytesAt( 31 | collection: abiMessage, 32 | index: index 33 | ) 34 | ) 35 | } 36 | 37 | /** 38 | - returns: 39 | Compact hex representation of a decoded number 40 | 41 | - throws: 42 | `DescribedError` if something went wrong 43 | */ 44 | public func value() throws -> Data { 45 | return try number.value() 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Web3Swift/ABI/Decoding/DecodedABIString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DecodedABIString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Decoded variable bytes interpreted as a utf8 string */ 14 | public final class DecodedABIString: StringScalar { 15 | 16 | private let origin: StringScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - abiMessage: message where string is located 23 | - index: position of the string 24 | */ 25 | public init( 26 | abiMessage: CollectionScalar, 27 | index: Int 28 | ) { 29 | self.origin = UTF8String( 30 | bytes: DecodedABIVariableBytes( 31 | abiMessage: abiMessage, 32 | index: index 33 | ) 34 | ) 35 | } 36 | 37 | /** 38 | - returns: 39 | Decoded string 40 | 41 | - throws: 42 | `DescribedError` if something went wrong 43 | */ 44 | public func value() throws -> String { 45 | return try self.origin.value() 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Web3Swift/ABI/EncodedABITuple.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EncodedABITuple.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes of the encoded abi tuple */ 14 | public final class EncodedABITuple: BytesScalar { 15 | 16 | private let encoding: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - parameters: parameters of the tuple 23 | */ 24 | public init(parameters: [ABIEncodedParameter]) { 25 | encoding = ConcatenatedBytes( 26 | bytes: ABITupleEncoding( 27 | parameters: parameters 28 | ) 29 | ) 30 | } 31 | 32 | /** 33 | - returns: 34 | Encoded tuple as `Data` 35 | 36 | - throws: 37 | `DescribedError` if something went wrong. 38 | */ 39 | public func value() throws -> Data { 40 | return try encoding.value() 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Web3Swift/ABI/EncodedContract.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EncodedContract.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Encoded initialized contract bytes */ 14 | public final class EncodedContract: BytesScalar { 15 | 16 | private let byteCode: BytesScalar 17 | private let arguments: [ABIEncodedParameter] 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - bytesCode: bytes code of the contract 24 | - arguments: arguments of the contract ctor 25 | */ 26 | public init( 27 | byteCode: BytesScalar, 28 | arguments: [ABIEncodedParameter] 29 | ) { 30 | self.byteCode = byteCode 31 | self.arguments = arguments 32 | } 33 | 34 | /** 35 | - returns: 36 | Bytes representation of the initialized contract 37 | */ 38 | public func value() throws -> Data { 39 | return try ConcatenatedBytes( 40 | bytes: [ 41 | byteCode, 42 | EncodedABITuple( 43 | parameters: arguments 44 | ) 45 | ] 46 | ).value() 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Web3Swift/ABI/Parameters/ABIEncodedParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ABIEncodedParameter.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** An encoded ABI parameter */ 14 | public protocol ABIEncodedParameter { 15 | 16 | /** 17 | - parameters: 18 | - offset: number of elements preceding the parameter tails 19 | 20 | - returns: 21 | A collection of 32 bytes pieces of the head of the encoded parameter. 22 | 23 | - throws: 24 | `DescribedError` if something went wrong 25 | */ 26 | func heads(offset: Int) throws -> [BytesScalar] 27 | 28 | /** 29 | - parameters: 30 | - offset: number of elements preceding the parameter tails 31 | 32 | - returns: 33 | A collection of 32 bytes pieces of the tail of the encoded parameter. Tail is empty for "static" parameters. 34 | 35 | - throws: 36 | `DescribedError` if something went wrong 37 | */ 38 | func tails(offset: Int) throws -> [BytesScalar] 39 | 40 | /** 41 | - returns: 42 | True if parameter is dynamic according to the ABI specification. False otherwise. 43 | */ 44 | func isDynamic() -> Bool 45 | 46 | /** 47 | - returns: 48 | A count of heads elements of the parameter 49 | */ 50 | func headsCount() -> Int 51 | 52 | } 53 | -------------------------------------------------------------------------------- /Web3Swift/Account/Account.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Account.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** An account that is associated with some private key on the network */ 14 | public protocol Account { 15 | 16 | /** 17 | TODO: I am not sure whether the Account should promise to return its balance in wei 18 | - returns: 19 | The amount of value the `Account` holds 20 | 21 | - throws: 22 | `DescribedError` if something went wrong 23 | */ 24 | func balance() throws -> BytesScalar 25 | 26 | /** 27 | Send the specified amount to the recipient 28 | 29 | - parameters: 30 | - weiAmount: amount to be sent in wei 31 | - recipientAddress: address of the recipient 32 | 33 | - returns: 34 | `TransactionHash` identifier of the transaction 35 | 36 | - throws: 37 | `DescribedError` if something went wrong 38 | */ 39 | func send(weiAmount: BytesScalar, to recipientAddress: BytesScalar) throws -> TransactionHash 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Web3Swift/Balance/EthBalance.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthBalance.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Balance of an address */ 14 | public final class EthBalance: BytesScalar { 15 | 16 | private let origin: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - network: network to ask for balance 23 | - address: address of the balance 24 | */ 25 | public init( 26 | network: Network, 27 | address: BytesScalar 28 | ) { 29 | self.origin = EthNumber( 30 | hex: SimpleString{ 31 | try BalanceProcedure( 32 | network: network, 33 | address: address, 34 | state: PendingBlockChainState() 35 | ).call()["result"].string() 36 | } 37 | ) 38 | } 39 | 40 | /** 41 | - returns: 42 | Balance in hex 43 | 44 | - throws: 45 | `DescribedError` if something went wrong 46 | */ 47 | public func value() throws -> Data { 48 | return try origin.value() 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/Blockchain/BlockChainState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BlockChainState.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol BlockChainState { 14 | 15 | func toString() throws -> String 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Web3Swift/Blockchain/EarliestBlockChainState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EarliestBlockChainState.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class EarliestBlockChainState: BlockChainState { 14 | 15 | public init() { } 16 | 17 | public func toString() throws -> String { 18 | return "earliest" 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Web3Swift/Blockchain/LatestBlockChainState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // LatestBlockChainState.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class LatestBlockChainState: BlockChainState { 14 | 15 | public init() { } 16 | 17 | public func toString() throws -> String { 18 | return "latest" 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Web3Swift/Blockchain/PendingBlockChainState.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // PendingBlockChainState.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class PendingBlockChainState: BlockChainState { 14 | 15 | public init() { } 16 | 17 | public func toString() throws -> String { 18 | return "pending" 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Web3Swift/Blocks/Block.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Block.swift 7 | // 8 | // Created by Vadim Koleoshkin on 20/05/2019 9 | // 10 | 11 | import Foundation 12 | 13 | //FIXME: Block description is not full 14 | /** Representation of Block mined on Ethereum blockchain */ 15 | public protocol Block { 16 | 17 | /** 18 | - returns: 19 | block number represented as `EthNumber` 20 | */ 21 | func number() throws -> EthNumber 22 | 23 | /** 24 | - returns: 25 | block hash represented as `BlockHash` 26 | */ 27 | func hash() throws -> BlockHash 28 | 29 | /** 30 | - returns: 31 | blocks parent hash represented as `BlockHash` 32 | */ 33 | func parentHash() throws -> BlockHash 34 | 35 | /** 36 | - returns: 37 | UNIX timestamp of block represented as `EthNumber` 38 | */ 39 | func timestamp() throws -> EthNumber 40 | 41 | /** 42 | - returns: 43 | List of transactions `Transaction` mined in the block 44 | */ 45 | func transactions() throws -> CollectionScalar 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Web3Swift/Blocks/BlockHash.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BlockHash.swift 7 | // 8 | // Created by Vadim Koleoshkin on 14/05/2019 9 | // 10 | 11 | import Foundation 12 | 13 | /** Standard ethereum block hash */ 14 | public protocol BlockHash: BytesScalar { 15 | 16 | /** 17 | Block representation of ethereum block hash 18 | 19 | - returns: 20 | `Block` object 21 | */ 22 | func block() throws -> Block 23 | } 24 | -------------------------------------------------------------------------------- /Web3Swift/BooleanScalar/BooleanScalar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BooleanScalar.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just a Bool */ 14 | public protocol BooleanScalar { 15 | 16 | /** 17 | - returns: 18 | Value of a boolean as `Bool` 19 | 20 | - throws: 21 | `DescribedError` if something went wrong 22 | */ 23 | func value() throws -> Bool 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Web3Swift/BooleanScalar/False.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // False.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just a false boolean value */ 14 | public final class False: BooleanScalar { 15 | 16 | /** 17 | - returns: 18 | false `Bool` 19 | 20 | - throws: 21 | Doesn't throw 22 | */ 23 | public func value() throws -> Bool { 24 | return false 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Web3Swift/BooleanScalar/SimpleBoolean.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleBoolean.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Anonymous boolean scalar wrapper */ 14 | public final class SimpleBoolean: BooleanScalar { 15 | 16 | private let bool: () throws -> (Bool) 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - bool: a closure that represents of a bool 23 | */ 24 | public init(bool: @escaping () throws -> (Bool)) { 25 | self.bool = bool 26 | } 27 | 28 | /** 29 | Ctor 30 | 31 | - parameters: 32 | - bool: just a boolean value 33 | */ 34 | public convenience init(bool: Bool) { 35 | self.init(bool: { bool }) 36 | } 37 | 38 | /** 39 | - returns: 40 | `Bool` representation of a scalar 41 | 42 | - throws: 43 | `DescribedError` if something went wrong 44 | */ 45 | public func value() throws -> Bool { 46 | return try bool() 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Web3Swift/BooleanScalar/True.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // True.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just a true9 boolean value */ 14 | public final class True: BooleanScalar { 15 | 16 | /** 17 | - returns: 18 | true `Bool` 19 | 20 | - throws: 21 | Doesn't throw 22 | */ 23 | public func value() throws -> Bool { 24 | return true 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/BytesFromCompactHexString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BytesFromCompactHexString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes from a compact hex string (without any leading zeroes) */ 14 | public final class BytesFromCompactHexString: BytesScalar { 15 | 16 | private let hex: StringScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - hex: hex string representation of the bytes. A leading zero is added if string representation is a valid hex of odd length. 23 | */ 24 | public init(hex: StringScalar) { 25 | self.hex = hex 26 | } 27 | 28 | /** 29 | - returns: 30 | bytes as `Data` represented by the compact hex string 31 | 32 | - throws: 33 | `DescribedError` if something went wrong 34 | */ 35 | public func value() throws -> Data { 36 | return try BytesFromHexString( 37 | hex: SimpleString{ 38 | let hex = try TrimmedPrefixString( 39 | string: self.hex, 40 | prefix: HexPrefix() 41 | ).value() 42 | if hex.count.isEven() { 43 | return hex 44 | } else { 45 | return "0" + hex 46 | } 47 | } 48 | ).value() 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/BytesFromHexString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BytesFromHexString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import CryptoSwift 12 | import Foundation 13 | 14 | /** Bytes from their string representation. The string representation of bytes must not be ambiguous. */ 15 | public final class BytesFromHexString: BytesScalar { 16 | 17 | private let hex: StringScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - hex: `StringScalar` representing bytes in hex format 24 | */ 25 | public init(hex: StringScalar) { 26 | self.hex = HexString(hex: hex) 27 | } 28 | 29 | /** 30 | Ctor 31 | 32 | - parameters: 33 | - hex: `String` representing bytes in hex format 34 | */ 35 | public convenience init(hex: String) { 36 | self.init( 37 | hex: SimpleString( 38 | string: hex 39 | ) 40 | ) 41 | } 42 | 43 | /** 44 | - returns: 45 | Bytes interpretation of the content of the string 46 | 47 | - throws: 48 | `DescribedError` if something went wrong 49 | */ 50 | public func value() throws -> Data { 51 | return try Data( 52 | hex: hex.value() 53 | ) 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/BytesScalar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BytesScalar.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just some bytes */ 14 | public protocol BytesScalar { 15 | 16 | /** 17 | - returns: 18 | bytes represented as `Data` 19 | */ 20 | func value() throws -> Data 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/CachedBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CachedBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Permanently cached bytes */ 14 | public final class CachedBytes: BytesScalar { 15 | 16 | private let stickyValue: StickyComputation 17 | 18 | /** 19 | - parameters: 20 | - origin: bytes to cache 21 | */ 22 | public init(origin: BytesScalar) { 23 | self.stickyValue = StickyComputation{ 24 | try origin.value() 25 | } 26 | } 27 | 28 | /** 29 | - returns: 30 | Bytes as `Data` of the cached origin 31 | 32 | - throws: 33 | `DescribedError` if something went wrong 34 | */ 35 | public func value() throws -> Data { 36 | return try stickyValue.result() 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/ConcatenatedBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ConcatenatedBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes concatenated into a single collection */ 14 | public final class ConcatenatedBytes: BytesScalar { 15 | 16 | private let bytes: CollectionScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters 22 | - bytes: a collection of bytes to be concatenated 23 | */ 24 | public init(bytes: CollectionScalar) { 25 | self.bytes = bytes 26 | } 27 | 28 | /** 29 | Ctor 30 | 31 | - parameters 32 | - bytes: a collection of bytes to be concatenated 33 | */ 34 | public convenience init(bytes: [BytesScalar]) { 35 | self.init(bytes: SimpleCollection(collection: bytes)) 36 | } 37 | 38 | /** 39 | - returns: 40 | bytes as `Data` of the bytes collection with respect to their position in the collection 41 | 42 | - throws: 43 | `DescribedError` if something went wrong 44 | */ 45 | public func value() throws -> Data { 46 | return try bytes.value().reduce(Data()) { 47 | try $0 + $1.value() 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/EmptyBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EmptyBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just empty bytes */ 14 | public final class EmptyBytes: BytesScalar { 15 | 16 | /** 17 | Ctor 18 | */ 19 | public init() { 20 | } 21 | 22 | /** 23 | - returns: 24 | Empty bytes as `Data` 25 | 26 | - throws: 27 | Doesn't throw 28 | */ 29 | public func value() throws -> Data { 30 | return Data([]) 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/FirstBit.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // FirstBit.swift 7 | // 8 | // Created by Timofey Solonin on 22/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** First (most significant) bit of a value */ 14 | public final class FirstBit: IntegerScalar { 15 | 16 | private let int: IntegerScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - value: value to take the bit from 23 | */ 24 | public init(value: IntegerScalar) { 25 | self.int = value 26 | } 27 | 28 | /** 29 | - returns: 30 | 0 if first bit is 0, 1 if first is 1 31 | */ 32 | public func value() throws -> Int { 33 | let value = try int.value() 34 | return Int( 35 | UInt(bitPattern: value) >> (value.bitWidth - 1) 36 | ) 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/FirstByte.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // FirstByte.swift 7 | // 8 | // Created by Timofey Solonin on 19/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** First byte of a bytes sequence */ 14 | public final class FirstByte: IntegerScalar { 15 | 16 | private let origin: CollectionScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: bytes to take first from 23 | */ 24 | public init(origin: CollectionScalar) { 25 | self.origin = SizeConstrainedCollection( 26 | origin: origin, 27 | minimum: 1 28 | ) 29 | } 30 | 31 | /** 32 | Ctor 33 | 34 | - parameters: 35 | - origin: bytes to take first from 36 | */ 37 | public convenience init(origin: BytesScalar) { 38 | self.init( 39 | origin: BytesAsCollection( 40 | origin: origin 41 | ) 42 | ) 43 | } 44 | 45 | //swiftlint:disable force_unwrapping 46 | /** 47 | - returns: 48 | First byte of the bytes sequence 49 | 50 | - throws: 51 | `DescribedError` if something went wrong. I.e. if bytes were empty. 52 | */ 53 | public func value() throws -> Int { 54 | return try Int( 55 | origin.value().first! 56 | ) 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/IntegerBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // IntegerBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes representation of an integer */ 14 | public final class IntegerBytes: BytesScalar { 15 | 16 | private let int: IntegerScalar 17 | 18 | public init(value: IntegerScalar) { 19 | self.int = value 20 | } 21 | 22 | /** 23 | Ctor 24 | 25 | - parameters: 26 | - value: an integer for which to get bytes. Endiannes should be specified in advanced. 27 | */ 28 | public convenience init(value: Int) { 29 | self.init( 30 | value: SimpleInteger{ value } 31 | ) 32 | } 33 | 34 | 35 | /** 36 | - returns: 37 | bytes as `Data` of the integer value. 38 | 39 | - throws: 40 | doesn't throw 41 | */ 42 | public func value() throws -> Data { 43 | var int = try self.int.value() 44 | return Data( 45 | bytes: &int, 46 | count: MemoryLayout.size(ofValue: int) 47 | ) 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/Keccak256Bytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Keccak256Bytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import CryptoSwift 12 | import Foundation 13 | 14 | /** Bytes digested by keccak256 algorithm */ 15 | public final class Keccak256Bytes: BytesScalar { 16 | 17 | private let origin: BytesScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - origin: bytes to digest 24 | */ 25 | public init(origin: BytesScalar) { 26 | self.origin = origin 27 | } 28 | 29 | /** 30 | - returns: 31 | Digested bytes as `Data` 32 | 33 | - throws: 34 | `DescribedError` if something went wrong. 35 | */ 36 | public func value() throws -> Data { 37 | return try Data( 38 | SHA3( 39 | variant: .keccak256 40 | ).calculate( 41 | for: Array( 42 | origin.value() 43 | ) 44 | ) 45 | ) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/LeftZeroesPaddedBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // LeftZeroesPaddedBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Pads bytes with zeroes to the left */ 14 | public final class LeftZeroesPaddedBytes: BytesScalar { 15 | 16 | private let origin: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: bytes to pad 23 | - padding: size to which to pad to 24 | */ 25 | public init( 26 | origin: BytesScalar, 27 | length: Int 28 | ) { 29 | self.origin = LeftPaddedBytes( 30 | origin: origin, 31 | element: SimpleInteger( 32 | integer: 0x00 33 | ), 34 | length: SimpleInteger( 35 | integer: length 36 | ) 37 | ) 38 | } 39 | 40 | /** 41 | - returns: 42 | Bytes as `Data` padded with zeroes to the right 43 | 44 | - throws: 45 | `DescribedError` if something went wrong 46 | */ 47 | public func value() throws -> Data { 48 | return try origin.value() 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/NumberHex.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // NumberHex.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Hex of a Number */ 14 | public class NumberHex: BytesScalar { 15 | 16 | private let number: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - number: number to take the hex from 23 | */ 24 | public init(number: BytesScalar) { 25 | self.number = number 26 | } 27 | 28 | /** 29 | - returns: 30 | Hex of the number as `Data` 31 | */ 32 | public func value() throws -> Data { 33 | return try number.value() 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/ReversedBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ReversedBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes in reversed order */ 14 | public final class ReversedBytes: BytesScalar { 15 | 16 | private let origin: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: origin to reverse 23 | */ 24 | public init(origin: BytesScalar) { 25 | self.origin = origin 26 | } 27 | 28 | /** 29 | - returns: 30 | Bytes of the origin in reversed order 31 | 32 | - throws: 33 | `DescribedError` if something went wrong 34 | */ 35 | public func value() throws -> Data { 36 | return try Data( 37 | origin.value().reversed() 38 | ) 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/TrailingCompactBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TrailingCompactBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes without trailing zeroes */ 14 | public final class TrailingCompactBytes: BytesScalar { 15 | 16 | private let compactOrigin: BytesScalar 17 | /** 18 | Ctor 19 | 20 | - parameters: 21 | - origin: bytes to be compacted 22 | */ 23 | public init(origin: BytesScalar) { 24 | self.compactOrigin = ReversedBytes( 25 | origin: TrimmedZeroPrefixBytes( 26 | origin: ReversedBytes( 27 | origin: origin 28 | ) 29 | ) 30 | ) 31 | } 32 | 33 | /** 34 | - returns: 35 | bytes as `Data` without trailing zeroes (first value in case it is zero is not considered trailing) 36 | 37 | - throws: 38 | `DescribedError` if something went wrong 39 | */ 40 | public func value() throws -> Data { 41 | return try compactOrigin.value() 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/Trimmed255PrefixBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Trimmed255PrefixBytes.swift 7 | // 8 | // Created by Timofey Solonin on 19/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes without leading ffs */ 14 | public final class Trimmed255PrefixBytes: BytesScalar { 15 | 16 | private let origin: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: bytes to trim 23 | */ 24 | public init( 25 | origin: BytesScalar 26 | ) { 27 | self.origin = TrimmedPrefixBytes( 28 | origin: origin, 29 | prefix: SimpleInteger( 30 | integer: 255 31 | ) 32 | ) 33 | } 34 | 35 | /** 36 | - returns: 37 | Bytes without leading ffs (last byte is not considered leading) 38 | */ 39 | public func value() throws -> Data { 40 | return try origin.value() 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/TrimmedPrefixBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TrimmedPrefixBytes.swift 7 | // 8 | // Created by Timofey Solonin on 19/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes without leading element */ 14 | public final class TrimmedPrefixBytes: BytesScalar { 15 | 16 | private let origin: BytesScalar 17 | private let prefix: IntegerScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - origin: bytes to trim 24 | - prefix: byte to trim the origin off 25 | */ 26 | public init( 27 | origin: BytesScalar, 28 | prefix: IntegerScalar 29 | ) { 30 | self.origin = origin 31 | self.prefix = RangeConstrainedInteger( 32 | origin: prefix, 33 | minimum: 0, 34 | maximum: 255 35 | ) 36 | } 37 | 38 | /** 39 | - returns: 40 | Bytes without the specified element in the lead (last byte is not considered leading). 41 | */ 42 | public func value() throws -> Data { 43 | let origin = try self.origin.value() 44 | let prefix = try self.prefix.value() 45 | return origin.dropLast().drop(while: { $0 == prefix }) + [origin.last].compactMap{ $0 } 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/TrimmedZeroPrefixBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TrimmedZeroPrefixBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes without leading zeroes */ 14 | public final class TrimmedZeroPrefixBytes: BytesScalar { 15 | 16 | private let origin: BytesScalar 17 | /** 18 | Ctor 19 | 20 | - parameters: 21 | - origin: bytes to trim 22 | */ 23 | public init(origin: BytesScalar) { 24 | self.origin = TrimmedPrefixBytes( 25 | origin: origin, 26 | prefix: SimpleInteger( 27 | integer: 0 28 | ) 29 | ) 30 | } 31 | 32 | /** 33 | - returns: 34 | bytes as `Data` without leading zeroes (last value in case it is zero is not considered leading) 35 | 36 | - throws: 37 | `DescribedError` if something went wrong 38 | */ 39 | public func value() throws -> Data { 40 | return try origin.value() 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Web3Swift/BytesScalar/UTF8StringBytes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UTF8StringBytes.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes of the string in UTF8 representation */ 14 | public final class UTF8StringBytes: BytesScalar { 15 | 16 | private let string: StringScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - string: string to be evaluated for bytes 23 | */ 24 | public init(string: StringScalar) { 25 | self.string = string 26 | } 27 | 28 | /** 29 | Ctor 30 | 31 | - parameters: 32 | - string: string to be evaluated for bytes 33 | */ 34 | public convenience init(string: String) { 35 | self.init( 36 | string: SimpleString{ string } 37 | ) 38 | } 39 | 40 | /** 41 | - returns: 42 | bytes as `Data` of the string interpreted as utf8 bytes collection 43 | 44 | - throws: 45 | `DescribedError` if something went wrong 46 | */ 47 | public func value() throws -> Data { 48 | return try Data( 49 | Array( 50 | string.value().utf8 51 | ) 52 | ) 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Web3Swift/CollectionScalar/BytesAsCollection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BytesAsCollection.swift 7 | // 8 | // Created by Timofey Solonin on 19/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Bytes as a collection of UInt8 byte pieces */ 14 | public final class BytesAsCollection: CollectionScalar { 15 | 16 | private let origin: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: bytes to represent as a collection 23 | */ 24 | public init(origin: BytesScalar) { 25 | self.origin = origin 26 | } 27 | 28 | /** 29 | - returns: 30 | A collection of bytes as `Array` 31 | */ 32 | public override func value() throws -> [UInt8] { 33 | return try Array( 34 | origin.value() 35 | ) 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /Web3Swift/CollectionScalar/CachedCollection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CachedCollection.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Permanently cached collection */ 14 | public final class CachedCollection: CollectionScalar { 15 | 16 | private let origin: StickyComputation<[T]> 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: origin to cache 23 | */ 24 | public init( 25 | origin: CollectionScalar 26 | ) { 27 | self.origin = StickyComputation{ try origin.value() } 28 | } 29 | 30 | /** 31 | - returns: 32 | Cached collection as `Array` of `T` 33 | 34 | - throws: 35 | `DescribedError` if something went wrong 36 | */ 37 | public override func value() throws -> [T] { 38 | return try origin.result() 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Web3Swift/CollectionScalar/CollectionScalar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CollectionScalar.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** 14 | I don't think introducing type erasure is a good idea. Lets stick with 15 | abstract class for now but move to proper interface if they will ever 16 | be introduced to Swift. 17 | */ 18 | /** Just a collection containing values of type T. All subclasses of this abstract class must be final. */ 19 | public class CollectionScalar { 20 | 21 | /** 22 | - returns: 23 | An `Array` representation of a collection 24 | 25 | - throws: 26 | Doesn't throw. Always errors out if super is called by the subclass. 27 | */ 28 | public func value() throws -> [T] { 29 | fatalError("CollectionScalar is an abstract class. Implement value() method and don't call super") 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Web3Swift/CollectionScalar/CollectionSuffix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CollectionSuffix.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Suffix (last n elements) of a collection */ 14 | public final class CollectionSuffix: CollectionScalar { 15 | 16 | private let origin: CollectionScalar 17 | private let from: IntegerScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - origin: origin to suffix of minimum size `from` + 1 24 | - from: index to suffix from 25 | */ 26 | public init( 27 | origin: CollectionScalar, 28 | from: IntegerScalar 29 | ) { 30 | self.origin = origin 31 | self.from = from 32 | } 33 | 34 | /** 35 | - returns: 36 | All elements after and including the specified index 37 | 38 | - throws: 39 | `DescribedError` if something went wrong 40 | */ 41 | public override func value() throws -> [T] { 42 | let from: Int = try self.from.value() 43 | return try Array( 44 | SizeConstrainedCollection( 45 | origin: origin, 46 | minimum: from + 1 47 | ).value() 48 | .suffix( 49 | from: Int( 50 | from 51 | ) 52 | ) 53 | ) 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Web3Swift/CollectionScalar/EnumeratedCollection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EnumeratedCollection.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** A collection of `T` numbering every element in the collection explicitly from 0 */ 14 | public final class EnumeratedCollection: CollectionScalar<(Int, T)> { 15 | 16 | private let origin: CollectionScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: origin to enumerate 23 | */ 24 | public init( 25 | origin: CollectionScalar 26 | ) { 27 | self.origin = origin 28 | } 29 | 30 | /** 31 | - returns: 32 | A collection as `Array` of elements with each element represented as number and a value 33 | 34 | - throws: 35 | `DescribedError` if something went wrong 36 | */ 37 | public override func value() throws -> [(Int, T)] { 38 | return try Array( 39 | origin.value().enumerated() 40 | ) 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /Web3Swift/CollectionScalar/MappedCollection.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // MappedCollection.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** A collection of elements mapped from `C` to `T` */ 14 | public final class MappedCollection: CollectionScalar { 15 | 16 | private let origin: CollectionScalar 17 | private let mapping: (C) throws -> (T) 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - origin: origin to map 24 | - mapping: closure for transforming `C` into `T` 25 | */ 26 | public init( 27 | origin: CollectionScalar, 28 | mapping: @escaping (C) throws -> (T) 29 | ) { 30 | self.origin = origin 31 | self.mapping = mapping 32 | } 33 | 34 | /** 35 | - returns: 36 | A collection of `T` as `Array` 37 | 38 | - throws: 39 | `DescribedError` if something went wrong 40 | */ 41 | public override func value() throws -> [T] { 42 | return try origin.value().map{ c in 43 | try mapping(c) 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Web3Swift/CollectionScalar/SizeOf.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SizeOf.swift 7 | // 8 | // Created by Timofey Solonin on 19/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** A size of a collection */ 14 | public final class SizeOf: IntegerScalar { 15 | 16 | private let collection: CollectionScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - collection: collection to count the length of 23 | */ 24 | public init(collection: CollectionScalar) { 25 | self.collection = MappedCollection( 26 | origin: collection, 27 | mapping: { $0 as Any } 28 | ) 29 | } 30 | 31 | /** 32 | - returns: 33 | Number of elements in the collection 34 | */ 35 | public func value() throws -> Int { 36 | return try collection.value().count 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /Web3Swift/DecimalScalar/DecimalFromHex.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DecimalFromHex.swift 7 | // 8 | // Created by Vadim Koleoshkin on 09/05/2019 9 | // 10 | 11 | import Foundation 12 | 13 | /** Hexadecimal unsigned big endian number represented as a Decimal number */ 14 | public final class DecimalFromHex: DecimalScalar { 15 | 16 | private let hex: BytesScalar 17 | 18 | public init(hex: BytesScalar) { 19 | self.hex = hex 20 | } 21 | 22 | /** 23 | - returns: 24 | Decimal representation of a hexadecimal 25 | */ 26 | public func value() throws -> Decimal { 27 | guard let value = try Decimal( 28 | string: HexAsDecimalString( 29 | hex: self.hex 30 | ).value() 31 | ) else { 32 | throw HexToDecimalConversionError( 33 | hex: try self.hex.value().toHexString() 34 | ) 35 | } 36 | return value; 37 | } 38 | 39 | } 40 | 41 | 42 | public final class HexToDecimalConversionError: DescribedError { 43 | 44 | private let hex: String 45 | 46 | public init(hex: String) { 47 | self.hex = hex 48 | } 49 | 50 | public var description: String { 51 | return "Unable to convert hex string \"\(hex)\" to decimal" 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /Web3Swift/DecimalScalar/DecimalScalar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DecimalScalar.swift 7 | // 8 | // Created by Vadim Koleoshkin on 09/05/2019 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just a Decimal number */ 14 | public protocol DecimalScalar { 15 | 16 | /** 17 | - returns: 18 | bytes represented as `Decimal` 19 | */ 20 | func value() throws -> Decimal 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Web3Swift/DecimalScalar/NormalizedDecimalFromHex.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // NormalizedDecimalFromHex.swift 7 | // 8 | // Created by Vadim Koleoshkin on 10/05/2019 9 | // 10 | 11 | import Foundation 12 | 13 | /** Hexadecimal unsigned big endian number represented as a Decimal number divided by 10^power */ 14 | public final class NormalizedDecimalFromHex: DecimalScalar { 15 | 16 | private let hex: BytesScalar 17 | private let power: Int 18 | 19 | public init(hex: BytesScalar, power: Int) { 20 | self.hex = hex 21 | self.power = power 22 | } 23 | 24 | /** 25 | - returns: 26 | Normalized Decimal representation of hexdecimal number 27 | */ 28 | public func value() throws -> Decimal { 29 | return try DecimalFromHex(hex: hex).value() / pow(Decimal(10), power) 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Web3Swift/Entropy/Entropy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Entropy.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol Entropy { 14 | 15 | func toData() throws -> Data 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Web3Swift/Entropy/RandomNonce.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // RandomNonce.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import Security 13 | 14 | public final class SecRandomError: Swift.Error { } 15 | 16 | public final class RandomNonce: Entropy { 17 | 18 | private let size: Int 19 | 20 | public init(size: Int) { 21 | self.size = Int(size) 22 | } 23 | 24 | private var cachedNonce: Data? 25 | 26 | public func toData() throws -> Data { 27 | if let nonce = cachedNonce { 28 | return nonce 29 | } else { 30 | var randomBytes = Array(repeating: 0, count: size) 31 | if SecRandomCopyBytes(kSecRandomDefault, size, &randomBytes) == errSecSuccess { 32 | let nonce = Data(randomBytes) 33 | cachedNonce = nonce 34 | return nonce 35 | } else { 36 | throw SecRandomError() 37 | } 38 | } 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Web3Swift/Errors/DescribedError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // DescribedError.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol DescribedError: Swift.Error, CustomStringConvertible { } 14 | -------------------------------------------------------------------------------- /Web3Swift/Extensions/BigUInt.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BigUInt.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | extension BigUInt { 15 | 16 | internal func subtractSafely(subtrahend: BigUInt) throws -> BigUInt { 17 | let difference = self.subtractingReportingOverflow(subtrahend) 18 | guard difference.overflow == false else { 19 | throw IntegerOverflow( 20 | firstTerm: self, 21 | secondTerm: subtrahend, 22 | operation: "subtraction" 23 | ) 24 | } 25 | return difference.partialValue 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /Web3Swift/Extensions/Data.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Data.swift 7 | // 8 | // Created by Vadim Koleoshkin on 11/05/2019 9 | // 10 | 11 | import Foundation 12 | 13 | extension Data { 14 | 15 | public func toDecimal() throws -> Decimal { 16 | return try DecimalFromHex( 17 | hex: SimpleBytes( 18 | bytes: self 19 | ) 20 | ).value() 21 | } 22 | 23 | public func toNormalizedDecimal(power: Int) throws -> Decimal { 24 | return try NormalizedDecimalFromHex( 25 | hex: SimpleBytes( 26 | bytes: self 27 | ), 28 | power: power 29 | ).value() 30 | } 31 | 32 | public func toDecimalString() throws -> String { 33 | return try HexAsDecimalString( 34 | hex: SimpleBytes( 35 | bytes: self 36 | ) 37 | ).value() 38 | } 39 | 40 | public func toPrefixedHexString() -> String { 41 | return "0x" + self.toHexString() 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Web3Swift/Extensions/Int.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Int.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | extension Int { 14 | 15 | internal func unsignedByteWidth() -> Int { 16 | return (self.bitWidth - self.leadingZeroBitCount - 1) / 8 + 1 17 | } 18 | 19 | /** 20 | Tells if Int is even (divisible by 2 with 0 as a remainder) 21 | 22 | - returns: 23 | true if even, false if odd 24 | */ 25 | internal func isEven() -> Bool { 26 | return self % 2 == 0 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Web3Swift/Extensions/URLPostRequest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // URLPostRequest.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | //FIXME: Init should throw since URLRequest is actually HTTPURLRequest 14 | internal final class URLPostRequest { 15 | 16 | private let url: URL 17 | private let body: Data 18 | private let headers: Dictionary 19 | internal init(url: URL, body: Data, headers: Dictionary) { 20 | self.url = url 21 | self.body = body 22 | self.headers = headers 23 | } 24 | 25 | internal func toURLRequest() -> URLRequest { 26 | var request = URLRequest(url: url) 27 | request.httpMethod = "POST" 28 | request.httpBody = body 29 | headers.forEach { 30 | request.addValue($0.value, forHTTPHeaderField: $0.key) 31 | } 32 | return request 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Web3Swift/Extensions/URLSession.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // URLSession.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | fileprivate class UnknownURLSessionError: DescribedError { 14 | 15 | public var description: String { 16 | return "Unknown URLSession error" 17 | } 18 | 19 | } 20 | 21 | extension URLSession { 22 | 23 | public func data(from request: URLRequest) throws -> Data { 24 | var data: Data? = nil 25 | var error: Error? = nil 26 | let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0) 27 | URLSession.shared.dataTask( 28 | with: request, 29 | completionHandler: { (taskData: Data?, response: URLResponse?, taskError: Error?) in 30 | if let response = response as? HTTPURLResponse, 31 | (200...299).contains(response.statusCode) { 32 | data = taskData 33 | } 34 | error = taskError 35 | semaphore.signal() 36 | }).resume() 37 | semaphore.wait() 38 | if let error = error { 39 | throw error 40 | } else if let data = data { 41 | return data 42 | } 43 | throw UnknownURLSessionError() 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Web3Swift/Functions/StickyComputation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // StickyComputation.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class StickyComputation { 14 | 15 | private let computation: () throws -> (ReturnType) 16 | public init(computation: @escaping () throws -> (ReturnType)) { 17 | self.computation = computation 18 | } 19 | 20 | private var computationResult: ReturnType? 21 | private var error: Swift.Error? 22 | public func result() throws -> ReturnType { 23 | if let computationResult = self.computationResult { 24 | return computationResult 25 | } else if let error = self.error { 26 | throw error 27 | } else { 28 | let computationResult = try self.computation() 29 | self.computationResult = computationResult 30 | return computationResult 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Web3Swift/GasPrice/EthGasPrice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthGasPrice.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Gas price computed by the network */ 14 | public final class EthGasPrice: BytesScalar { 15 | 16 | private let price: BytesScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - network: network to ask for gas price 23 | */ 24 | public init(network: Network) { 25 | self.price = EthNumber( 26 | hex: SimpleString{ 27 | try GetGasPriceProcedure( 28 | network: network 29 | ).call()["result"].string() 30 | } 31 | ) 32 | } 33 | 34 | /** 35 | - returns: 36 | Compact hex representation of a gas price 37 | 38 | - throws: 39 | `DescribedError` if something goes wrong 40 | */ 41 | public func value() throws -> Data { 42 | return try price.value() 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/BigEndianInteger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BigEndianInteger.swift 7 | // 8 | // Created by Timofey Solonin on 16/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Big endian representation of an integer */ 14 | public final class BigEndianInteger: IntegerScalar { 15 | 16 | private let origin: IntegerScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: origin to take big endian representation from 23 | */ 24 | public init(origin: IntegerScalar) { 25 | self.origin = origin 26 | } 27 | 28 | /** 29 | - returns: 30 | Integer with a big endian binary representation. On a little endian platform it will be an integer with its bytes reversed. 31 | */ 32 | public func value() throws -> Int { 33 | return try origin.value().bigEndian 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/CachedInteger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CachedNumber.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Permanently cached integer */ 14 | public final class CachedInteger: IntegerScalar { 15 | 16 | private let stickyInt: StickyComputation 17 | 18 | /** 19 | - parameters: 20 | - origin: integer to cache 21 | */ 22 | public init(origin: IntegerScalar) { 23 | self.stickyInt = StickyComputation{ 24 | try origin.value() 25 | } 26 | } 27 | 28 | /** 29 | - returns: 30 | `Int` representation of cached origin 31 | 32 | - throws: 33 | `DescribedError` if something went wrong 34 | */ 35 | public func value() throws -> Int { 36 | return try stickyInt.result() 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/IntegerScalar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // NumberScalar.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just a number */ 14 | public protocol IntegerScalar { 15 | 16 | /** 17 | Integer representation of a number 18 | */ 19 | func value() throws -> Int 20 | 21 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/IntegerTypeSize.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // IntegerTypeSize.swift 7 | // 8 | // Created by Timofey Solonin on 22/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Int size in bytes. */ 14 | public final class IntegerTypeSize: IntegerScalar { 15 | 16 | /** 17 | - returns: 18 | Int size in bytes. I.e. Int64 is 8 bytes and Int32 is 7 bytes. 19 | */ 20 | public func value() throws -> Int { 21 | return MemoryLayout.size 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/IntegersDifference.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // IntegersDifference.swift 7 | // 8 | // Created by Timofey Solonin on 17/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Difference between integers */ 14 | public final class IntegersDifference: IntegerScalar { 15 | 16 | private let minuend: IntegerScalar 17 | private let subtrahend: IntegerScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - minuend: integer to subtract from 24 | - subtrahend: integer to subtract 25 | */ 26 | public init(minuend: IntegerScalar, subtrahend: IntegerScalar) { 27 | self.minuend = minuend 28 | self.subtrahend = subtrahend 29 | } 30 | 31 | /** 32 | - returns: 33 | Difference between minuend and subtrahend as minuend - subtrahend 34 | 35 | - throws: 36 | `DescribedError` if something went wrong. I.e. if difference results in an overflow 37 | */ 38 | public func value() throws -> Int { 39 | return try subtrahend.value().subtractSafely(from: minuend.value()) 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/IntegersEquality.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // IntegerEquality.swift 7 | // 8 | // Created by Timofey Solonin on 19/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Boolean equality of two integers */ 14 | public final class IntegersEquality: BooleanScalar { 15 | 16 | private let lhs: IntegerScalar 17 | private let rhs: IntegerScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - lhs: first integer 24 | - rhs: second integer 25 | */ 26 | public init(lhs: IntegerScalar, rhs: IntegerScalar) { 27 | self.lhs = lhs 28 | self.rhs = rhs 29 | } 30 | 31 | /** 32 | - returns: 33 | True is integers are equal, false if they are not 34 | */ 35 | public func value() throws -> Bool { 36 | return try lhs.value() == rhs.value() 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/IntegersQuotient.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // IntegersQuotient.swift 7 | // 8 | // Created by Timofey Solonin on 17/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Quotient of two integers */ 14 | public final class IntegersQuotient: IntegerScalar { 15 | 16 | private let dividend: IntegerScalar 17 | private let divisor: IntegerScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - dividend: number to divide 24 | - divisor: number to divide by 25 | */ 26 | public init(dividend: IntegerScalar, divisor: IntegerScalar) { 27 | self.dividend = dividend 28 | self.divisor = divisor 29 | } 30 | 31 | /** 32 | - returns: 33 | Quotient of integers dividend and divisor as dividend / divisor dropping decimal part. 34 | 35 | - throws: 36 | `DescribedError` if something went wrong. I.e. if divided by 0 or Int.min by -1. 37 | */ 38 | public func value() throws -> Int { 39 | return try dividend.value().divideSafely(by: divisor.value()) 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/NaturalInteger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // NaturalInteger.swift 7 | // 8 | // Created by Timofey Solonin on 22/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Integer from 0 to Int.max */ 14 | public final class NaturalInteger: IntegerScalar { 15 | 16 | private let origin: IntegerScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: integer to constraint to a natural set 23 | */ 24 | public init(origin: IntegerScalar) { 25 | self.origin = RangeConstrainedInteger( 26 | origin: origin, 27 | minimum: 0, 28 | maximum: Int.max 29 | ) 30 | } 31 | 32 | /** 33 | - returns: 34 | Integer that is between 0 and Int.max 35 | 36 | - throws: 37 | `DescribedError` if something went wrong. I.e. if value was not in a natural set. 38 | */ 39 | public func value() throws -> Int { 40 | return try origin.value() 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/SimpleInteger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleInteger.swift 7 | // 8 | // Created by Timofey Solonin on 15/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Anonymous integer implementation */ 14 | public final class SimpleInteger: IntegerScalar { 15 | 16 | private let integer: () throws -> (Int) 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - integer: closure representation of an integer 23 | */ 24 | public init(integer: @escaping () throws -> (Int)) { 25 | self.integer = integer 26 | } 27 | 28 | /** 29 | Ctor 30 | 31 | - parameters: 32 | - integer: just an integer 33 | */ 34 | public convenience init(integer: Int) { 35 | self.init(integer: { integer }) 36 | } 37 | 38 | /** 39 | - returns: 40 | Integer represented by the computation 41 | 42 | - throws: 43 | `DescribedError` if something went wrong 44 | */ 45 | public func value() throws -> Int { 46 | return try integer() 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /Web3Swift/IntegerScalar/TernaryInteger.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TernaryInteger.swift 7 | // 8 | // Created by Timofey Solonin on 22/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Integer value that is based on a boolean evaluation */ 14 | public final class TernaryInteger: IntegerScalar { 15 | 16 | private let ternary: Ternary 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - if: boolean condition for definition of integer 23 | - then: integer representation associated with true 24 | - else: integer representation associated with false 25 | */ 26 | public init( 27 | if: BooleanScalar, 28 | then: IntegerScalar, 29 | else: IntegerScalar 30 | ) { 31 | self.ternary = Ternary( 32 | if: `if`, 33 | then: { try then.value() }, 34 | else: { try `else`.value() } 35 | ) 36 | } 37 | 38 | /** 39 | - returns: 40 | If `if` is true, then `then`, else `else` 41 | */ 42 | public func value() throws -> Int { 43 | return try ternary.value() 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /Web3Swift/Network/AlchemyNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // AlchemyNetwork.swift 7 | // 8 | // Created by Vadim Koleoshkin on 27/03/2019 9 | // 10 | 11 | import Foundation 12 | 13 | /** alchemyapi.io network */ 14 | public final class AlchemyNetwork: Network { 15 | 16 | private let origin: GethNetwork 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - chain: chain identifier 23 | - apiKey: api key for accessing JSON RPC calls 24 | */ 25 | public init(chain: String, apiKey: String) { 26 | origin = GethNetwork(url: "https://eth-"+chain.lowercased()+".alchemyapi.io/v2/"+apiKey) 27 | } 28 | 29 | /** 30 | - returns: 31 | id of a network 32 | 33 | - throws: 34 | `DescribedError` if something went wrong 35 | */ 36 | public func id() throws -> IntegerScalar { 37 | return try origin.id() 38 | } 39 | 40 | /** 41 | - returns: 42 | `Data` for a JSON RPC call 43 | 44 | - throws: 45 | `DescribedError` if something went wrong 46 | */ 47 | public func call(method: String, params: Array) throws -> Data { 48 | return try origin.call(method: method, params: params) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/Network/GethNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // GethNetwork.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** A network of go ethereum implementation */ 14 | public final class GethNetwork: Network { 15 | 16 | private let origin: Network 17 | 18 | /** 19 | - parameters: 20 | - url: url for accessing JSON RPC 21 | */ 22 | public init(url: String) { 23 | self.origin = VerifiedNetwork( 24 | origin: EthNetwork( 25 | session: URLSession(configuration: URLSessionConfiguration.default), 26 | url: url, 27 | headers: [ 28 | "Accept": "application/json", 29 | "Content-Type": "application/json" 30 | ] 31 | ) 32 | ) 33 | } 34 | 35 | /** 36 | - returns: 37 | id of a network 38 | 39 | - throws: 40 | `DescribedError` if something went wrong 41 | */ 42 | public func id() throws -> IntegerScalar { 43 | return try origin.id() 44 | } 45 | 46 | /** 47 | - returns: 48 | `Data` for a JSON RPC call 49 | 50 | - throws: 51 | `DescribedError` if something went wrong 52 | */ 53 | public func call(method: String, params: Array) throws -> Data { 54 | return try origin.call(method: method, params: params) 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Web3Swift/Network/InfuraNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // InfuraNetwork.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** infura.io network */ 14 | public final class InfuraNetwork: Network { 15 | 16 | private let origin: GethNetwork 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - chain: chain identifier 23 | - apiKey: api key for accessing JSON RPC calls 24 | */ 25 | public init(chain: String, apiKey: String) { 26 | origin = GethNetwork(url: "https://"+chain+".infura.io/v3/"+apiKey) 27 | } 28 | 29 | /** 30 | - returns: 31 | id of a network 32 | 33 | - throws: 34 | `DescribedError` if something went wrong 35 | */ 36 | public func id() throws -> IntegerScalar { 37 | return try origin.id() 38 | } 39 | 40 | /** 41 | - returns: 42 | `Data` for a JSON RPC call 43 | 44 | - throws: 45 | `DescribedError` if something went wrong 46 | */ 47 | public func call(method: String, params: Array) throws -> Data { 48 | return try origin.call(method: method, params: params) 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/Network/Network.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Network.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol Network { 14 | 15 | /** 16 | - returns: 17 | id of a network 18 | 19 | - throws: 20 | `DescribedError` if something went wrong 21 | */ 22 | func id() throws -> IntegerScalar 23 | 24 | /** 25 | - returns: 26 | `Data` for a JSON RPC call 27 | 28 | - throws: 29 | `DescribedError` if something went wrong 30 | */ 31 | func call(method: String, params: Array) throws -> Data 32 | 33 | } 34 | -------------------------------------------------------------------------------- /Web3Swift/Network/NetworkID.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // NetworkID.swift 7 | // 8 | // Created by Timofey Solonin on 16/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class NetworkID: IntegerScalar { 14 | 15 | private let network: Network 16 | public init(network: Network) { 17 | self.network = network 18 | } 19 | 20 | public func value() throws -> Int { 21 | return try network.id().value() 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /Web3Swift/Network/SimpleNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleNetwork.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Anonymous network */ 14 | public final class SimpleNetwork: Network { 15 | 16 | private let identifier: () throws -> (IntegerScalar) 17 | private let response: (String, [EthParameter]) throws -> (Data) 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - id: closure representation of the id of the network 24 | - call: closure representation of the call response 25 | */ 26 | public init( 27 | id: @escaping () throws -> (IntegerScalar), 28 | call: @escaping (String, [EthParameter]) throws -> (Data) 29 | ) { 30 | self.identifier = id 31 | self.response = call 32 | } 33 | 34 | /** 35 | - returns: 36 | id of the network 37 | 38 | - throws: 39 | `DescribedError` if something went wrong 40 | */ 41 | public func id() throws -> IntegerScalar { 42 | return try self.identifier() 43 | } 44 | 45 | /** 46 | - returns: 47 | `Data` for a JSON RPC call 48 | 49 | - throws: 50 | `DescribedError` if something went wrong 51 | */ 52 | public func call(method: String, params: Array) throws -> Data { 53 | return try self.response( 54 | method, 55 | params 56 | ) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Web3Swift/Network/VerifiedNetwork.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // VerifiedNetwork.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Network with an error verified call */ 15 | public final class VerifiedNetwork: Network { 16 | 17 | private let origin: Network 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - origin: network to verify 24 | */ 25 | public init(origin: Network) { 26 | self.origin = origin 27 | } 28 | 29 | /** 30 | - returns: 31 | id of a network 32 | 33 | - throws: 34 | `DescribedError` if something went wrong 35 | */ 36 | public func id() throws -> IntegerScalar { 37 | return try origin.id() 38 | } 39 | 40 | 41 | /** 42 | - returns: 43 | `Data` for a JSON RPC call 44 | 45 | - throws: 46 | `DescribedError` if something went wrong 47 | */ 48 | public func call(method: String, params: Array) throws -> Data { 49 | return try VerifiedProcedure( 50 | origin: SimpleProcedure( 51 | json: JSON( 52 | origin.call( 53 | method: method, 54 | params: params 55 | ) 56 | ) 57 | ) 58 | ).call().rawData() 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/ArithmeticFunctions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ArithmeticFunctions.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public func -(left: BytesScalar, right: BytesScalar) -> BytesScalar { 14 | return UnsignedNumbersDifference( 15 | minuend: left, 16 | subtrahend: right 17 | ) 18 | } 19 | 20 | public func +(left: BytesScalar, right: BytesScalar) -> BytesScalar { 21 | return UnsignedNumbersSum( 22 | terms: [ 23 | left, 24 | right 25 | ] 26 | ) 27 | } 28 | 29 | public func *(left: BytesScalar, right: BytesScalar) -> BytesScalar { 30 | return UnsignedNumbersProduct( 31 | terms: [ 32 | left, 33 | right 34 | ] 35 | ) 36 | } 37 | 38 | public func /(left: BytesScalar, right: BytesScalar) -> BytesScalar { 39 | return UnsignedNumbersQuotient( 40 | dividend: left, 41 | divisor: right 42 | ) 43 | } 44 | 45 | public func ==(left: BytesScalar, right: BytesScalar) -> BooleanScalar { 46 | return UnsignedNumbersEquality( 47 | lhs: left, 48 | rhs: right 49 | ) 50 | } 51 | -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/HexAsDecimalString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // NumberAsDecimalString.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | /** Hexadecimal unsigned big endian number as a decimal number represented as string */ 15 | public final class HexAsDecimalString: StringScalar { 16 | 17 | private let hex: BytesScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - hex: hexadecimal representation of a number 24 | */ 25 | public init( 26 | hex: BytesScalar 27 | ) { 28 | self.hex = hex 29 | } 30 | 31 | /** 32 | - returns: 33 | Decimal string representation of a hexadecimal representation 34 | */ 35 | public func value() throws -> String { 36 | return try String( 37 | BigUInt( 38 | hex.value() 39 | ), 40 | radix: 10 41 | ) 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/UnsignedNumbersDifference.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnsignedNumbersDifference.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | /** A difference of unsigned big endian numbers of arbitrary length */ 15 | public final class UnsignedNumbersDifference: BytesScalar { 16 | 17 | private let minuend: BytesScalar 18 | private let subtrahend: BytesScalar 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - minuend: integer to subtract from 25 | - subtrahend: integer to subtract 26 | */ 27 | public init( 28 | minuend: BytesScalar, 29 | subtrahend: BytesScalar 30 | ) { 31 | self.minuend = minuend 32 | self.subtrahend = subtrahend 33 | } 34 | 35 | /** 36 | - returns: 37 | Difference between minuend and subtrahend as minuend - subtrahend 38 | */ 39 | public func value() throws -> Data { 40 | return try BigUInt( 41 | minuend.value() 42 | ).subtractSafely( 43 | subtrahend: BigUInt( 44 | subtrahend.value() 45 | ) 46 | ).serialize() 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/UnsignedNumbersEquality.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnsignedNumbersEquality.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | /** An equality of unsigned big endian numbers of arbitrary length */ 15 | public final class UnsignedNumbersEquality: BooleanScalar { 16 | 17 | private let lhs: BytesScalar 18 | private let rhs: BytesScalar 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - lhs: first number 25 | - rhs: second number 26 | */ 27 | public init(lhs: BytesScalar, rhs: BytesScalar) { 28 | self.lhs = lhs 29 | self.rhs = rhs 30 | } 31 | 32 | /** 33 | - returns: 34 | True if numbers are equal, else false 35 | */ 36 | public func value() throws -> Bool { 37 | return try BigUInt( 38 | lhs.value() 39 | ) == BigUInt( 40 | rhs.value() 41 | ) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/UnsignedNumbersExponentiation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnsignedNumbersExponentiation.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | /** An exponentiation of unsigned big endian numbers of arbitrary length */ 15 | public final class UnsignedNumbersExponentiation: BytesScalar { 16 | 17 | private let base: BytesScalar 18 | private let exponent: IntegerScalar 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - base: number to raise to power 25 | - exponent: power to raise to 26 | */ 27 | public init( 28 | base: BytesScalar, 29 | exponent: IntegerScalar 30 | ) { 31 | self.base = base 32 | self.exponent = NaturalInteger( 33 | origin: exponent 34 | ) 35 | } 36 | 37 | /** 38 | - returns: 39 | Number raised to the specified power 40 | */ 41 | public func value() throws -> Data { 42 | return try BigUInt( 43 | base.value() 44 | ).power( 45 | exponent.value() 46 | ).serialize() 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/UnsignedNumbersProduct.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnsignedNumbersProduct.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | /** A product of unsigned big endian numbers of arbitrary length */ 15 | public final class UnsignedNumbersProduct: BytesScalar { 16 | 17 | private let terms: CollectionScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - terms: terms to multiply 24 | */ 25 | public init( 26 | terms: CollectionScalar 27 | ) { 28 | self.terms = MappedCollection( 29 | origin: terms, 30 | mapping: { term in 31 | try BigUInt( 32 | term.value() 33 | ) 34 | } 35 | ) 36 | } 37 | 38 | /** 39 | Ctor 40 | 41 | - parameters: 42 | - terms: terms to multiply 43 | */ 44 | public convenience init( 45 | terms: [BytesScalar] 46 | ) { 47 | self.init( 48 | terms: SimpleCollection( 49 | collection: terms 50 | ) 51 | ) 52 | } 53 | 54 | /** 55 | - returns: 56 | Product of terms T as (T1 * T2 * T3 ... * Tn) 57 | */ 58 | public func value() throws -> Data { 59 | return try terms.value().reduce(BigUInt(1)) { token, term in 60 | token * term 61 | }.serialize() 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/UnsignedNumbersQuotient.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnsignedNumbersQuotient.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | /** A quotient of unsigned big endian numbers of arbitrary length */ 15 | public final class UnsignedNumbersQuotient: BytesScalar { 16 | 17 | private let dividend: BytesScalar 18 | private let divisor: BytesScalar 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - dividend: number to divide 25 | - divisor: number to divide by 26 | */ 27 | public init( 28 | dividend: BytesScalar, 29 | divisor: BytesScalar 30 | ) { 31 | self.dividend = dividend 32 | self.divisor = divisor 33 | } 34 | 35 | /** 36 | - returns: 37 | Quotient of integers dividend and divisor as dividend / divisor dropping decimal part. 38 | */ 39 | public func value() throws -> Data { 40 | let divisor = try BigUInt( 41 | self.divisor.value() 42 | ) 43 | guard divisor != 0 else { 44 | throw DivisionByZero() 45 | } 46 | return try ( 47 | BigUInt( 48 | dividend.value() 49 | ) / divisor 50 | ).serialize() 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/UnsignedNumbersSum.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnsignedNumbersSum.swift 7 | // 8 | // Created by Timofey Solonin on 23/05/2018 9 | // 10 | 11 | import BigInt 12 | import Foundation 13 | 14 | /** A sum of unsigned big endian numbers of arbitrary length */ 15 | public final class UnsignedNumbersSum: BytesScalar { 16 | 17 | private let terms: CollectionScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - terms: terms to sum 24 | */ 25 | public init( 26 | terms: CollectionScalar 27 | ) { 28 | self.terms = MappedCollection( 29 | origin: terms, 30 | mapping: { term in 31 | try BigUInt( 32 | term.value() 33 | ) 34 | } 35 | ) 36 | } 37 | 38 | /** 39 | Ctor 40 | 41 | - parameters: 42 | - terms: terms to sum 43 | */ 44 | public convenience init( 45 | terms: [BytesScalar] 46 | ) { 47 | self.init( 48 | terms: SimpleCollection( 49 | collection: terms 50 | ) 51 | ) 52 | } 53 | 54 | /** 55 | - returns: 56 | Sum of terms T as (T1 + T2 + T3 ... + Tn) 57 | */ 58 | public func value() throws -> Data { 59 | return try terms.value().reduce(BigUInt(0)) { token, value in 60 | token + value 61 | }.serialize() 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /Web3Swift/NumberScalar/Zero.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Zero.swift 7 | // 8 | // Created by Vadim Koleoshkin on 23/04/2019 9 | // 10 | 11 | import Foundation 12 | 13 | /** Unsigned big endian zero number */ 14 | public final class Zero: BytesScalar { 15 | 16 | private let zero: BytesScalar = EthNumber(value: 0) 17 | 18 | /** 19 | Ctor 20 | */ 21 | public init() { 22 | } 23 | 24 | /** 25 | - returns: 26 | Bytes representation of a zero ethereum number 27 | */ 28 | public func value() throws -> Data { 29 | return try zero.value() 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Web3Swift/Params/BooleanParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BooleanParameter.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class BooleanParameter: EthParameter { 14 | 15 | private var param: Bool 16 | 17 | public init(value: Bool) { 18 | self.param = value 19 | } 20 | 21 | public func value() throws -> Any { 22 | return param 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Web3Swift/Params/BytesParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BytesParameter.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class BytesParameter: EthParameter { 14 | 15 | private let bytes: BytesScalar 16 | 17 | /** 18 | Ctor 19 | 20 | - parameters: 21 | - bytes: unstructed data to be passed to network 22 | */ 23 | public init(bytes: BytesScalar) { 24 | self.bytes = bytes 25 | } 26 | 27 | /** 28 | - returns: 29 | `String` representation of the unstructured bytes as specified by ethereum JSON RPC 30 | 31 | - throws: 32 | `DescribedError` is something went wrong 33 | */ 34 | public func value() throws -> Any { 35 | return try PrefixedHexString( 36 | bytes: bytes 37 | ).value() 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Web3Swift/Params/EthParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthParameter.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Parameter to be passed to the network */ 14 | public protocol EthParameter { 15 | 16 | /** 17 | - returns: 18 | one of the types accepted by default swift encoder. Unfortunately they do not share any interface for the purpose of encoding and have to passed as `Any`. 19 | 20 | - throws: 21 | `DescribedError` is something went wrong 22 | */ 23 | func value() throws -> Any 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Web3Swift/Params/ObjectParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ObjectParameter.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | public final class ObjectParameter: EthParameter { 15 | 16 | private let dictionary: Dictionary 17 | public init(dictionary: Dictionary) { 18 | self.dictionary = dictionary 19 | } 20 | 21 | public func value() throws -> Any { 22 | return try dictionary.mapValues { 23 | try $0.value() 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Web3Swift/Params/QuantityParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // QuantityParameter.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class QuantityParameter: EthParameter { 14 | 15 | private let number: BytesScalar 16 | 17 | /** 18 | Ctor 19 | 20 | - parameters: 21 | - number: number to be converted to parameter 22 | */ 23 | public init(number: BytesScalar) { 24 | self.number = number 25 | } 26 | 27 | /** 28 | - returns: 29 | `String` representation of the number as specified by ethereum JSON RPC (dropping any leading zeroes in string representation) 30 | 31 | - throws: 32 | `DescribedError` is something went wrong 33 | */ 34 | public func value() throws -> Any { 35 | return try HexPrefixedString( 36 | origin: CompactHexString( 37 | bytes: number 38 | ) 39 | ).value() 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Web3Swift/Params/TagParameter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TagParameter.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class TagParameter: EthParameter { 14 | 15 | private var state: BlockChainState 16 | 17 | public init(state: BlockChainState) { 18 | self.state = state 19 | } 20 | 21 | public func value() throws -> Any { 22 | return try state.toString() 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Web3Swift/PrivateKey/PrivateKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // PrivateKey.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** A private key */ 14 | public protocol PrivateKey: BytesScalar { 15 | 16 | /** 17 | - returns: 18 | address evaluated from the private key. This is not a public key 19 | 20 | - throws: 21 | `DescribedError` if something went wrong 22 | */ 23 | func address() throws -> BytesScalar 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Web3Swift/PrivateKey/PrivateKeyAddress.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // PrivateKeyAddress.swift 7 | // 8 | // Created by Timofey Solonin on 12/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Address of the private key */ 14 | public final class PrivateKeyAddress: BytesScalar { 15 | 16 | private let key: PrivateKey 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - key: key to take the address from 23 | */ 24 | public init(key: PrivateKey) { 25 | self.key = key 26 | } 27 | 28 | /** 29 | - returns: 30 | Address of the private key 31 | 32 | - throws: 33 | `DescribedError` if something went wrong 34 | */ 35 | public func value() throws -> Data { 36 | return try key.address().value() 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /Web3Swift/RLP/EthRLP.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthRLP.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** 14 | An encoding specific to ethereum quantities 15 | 16 | Ethereum imposes a specific requirement on RLP encoding for quantities: 17 | https://ethereum.stackexchange.com/questions/30518/does-rlp-specify-integer-encoding 18 | */ 19 | public final class EthRLP: RLP { 20 | 21 | private let number: BytesScalar 22 | 23 | /** 24 | Ctor 25 | 26 | - parameters: 27 | - number: number to be encoded 28 | */ 29 | public init(number: BytesScalar) { 30 | self.number = number 31 | } 32 | 33 | /** 34 | - returns: 35 | Bytes as `Data` representing RLP encoded ethereum quantity encoding 0 as empty byte array 36 | 37 | - throws: 38 | `DescribedError` if something went wrong 39 | */ 40 | public func value() throws -> Data { 41 | let encodedNumber = try SimpleRLP( 42 | bytes: number.value() 43 | ).value() 44 | if encodedNumber == Data([0x00]) { 45 | return try SimpleRLP( 46 | bytes: [] 47 | ).value() 48 | } else { 49 | return encodedNumber 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Web3Swift/RLP/RLP.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // RLP.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol RLP: BytesScalar { } 14 | -------------------------------------------------------------------------------- /Web3Swift/RLP/RLPAppendix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // RLPAppendix.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol RLPAppendix { 14 | 15 | func applying(to: Data) throws -> Data 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Web3Swift/RLP/RLPBytesAppendix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // RLPBytesAppendix.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class RLPBytesAppendix: RLPAppendix { 14 | 15 | public func applying(to bytes: Data) throws -> Data { 16 | switch bytes.count { 17 | case 1 where try bytes.single() < 0x80: 18 | return bytes 19 | default: 20 | return try RLPStandardAppendix( 21 | offset: 0x80 22 | ).applying(to: bytes) 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Web3Swift/RLP/RLPCollectionsAppendix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // RLPCollectionsAppendix.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class RLPCollectionAppendix: RLPAppendix { 14 | 15 | public func applying(to bytes: Data) throws -> Data { 16 | return try RLPStandardAppendix( 17 | offset: 0xc0 18 | ).applying(to: bytes) 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /Web3Swift/RLP/RLPStandardAppendix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // RLPStandardAppendix.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class BytesLengthOverflow: Swift.Error { } 14 | 15 | internal final class RLPStandardAppendix: RLPAppendix { 16 | 17 | private let offset: UInt8 18 | public init(offset: UInt8) { 19 | self.offset = offset 20 | } 21 | 22 | internal func applying(to bytes: Data) throws -> Data { 23 | switch bytes.count { 24 | case 0...55: 25 | return Data( 26 | [ 27 | UInt8( 28 | UInt8(bytes.count) + offset 29 | ) 30 | ] 31 | ) + bytes 32 | case 56...Int.max: 33 | return try Data( 34 | [ 35 | UInt8(bytes.count.unsignedByteWidth() + Int(offset) + 55) 36 | ] 37 | ) + TrimmedZeroPrefixBytes( 38 | origin: IntegerBytes( 39 | value: bytes.count.bigEndian 40 | ) 41 | ).value() + bytes 42 | default: 43 | throw BytesLengthOverflow() 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /Web3Swift/RLP/SimpleRLP.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleRLP.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class SimpleRLP: RLP { 14 | 15 | private let bytes: BytesScalar 16 | private let appendix: RLPAppendix 17 | 18 | private init(bytes: BytesScalar, appendix: RLPAppendix) { 19 | self.bytes = bytes 20 | self.appendix = appendix 21 | } 22 | 23 | public convenience init(bytes: BytesScalar) { 24 | self.init( 25 | bytes: bytes, 26 | appendix: RLPBytesAppendix() 27 | ) 28 | } 29 | 30 | public convenience init(bytes: Data) { 31 | self.init( 32 | bytes: SimpleBytes( 33 | bytes: bytes 34 | ) 35 | ) 36 | } 37 | 38 | public convenience init(bytes: Array) { 39 | self.init( 40 | bytes: SimpleBytes( 41 | bytes: bytes 42 | ) 43 | ) 44 | } 45 | 46 | public convenience init(rlps: [RLP]) { 47 | self.init( 48 | bytes: ConcatenatedBytes(bytes: rlps), 49 | appendix: RLPCollectionAppendix() 50 | ) 51 | } 52 | 53 | public func value() throws -> Data { 54 | return try appendix.applying(to: bytes.value()) 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/BlockByHashProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // BlockByHashProcedure.swift 7 | // 8 | // Created by Vadim Koleoshkin on 21/05/2019 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Procedure for fetching block by hash */ 15 | public final class BlockByHashProcedure: RemoteProcedure { 16 | 17 | private let network: Network 18 | private let blockHash: BytesScalar 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - network: network to ask for transaction 25 | - blockHash: hash of the raw block 26 | */ 27 | public init( 28 | network: Network, 29 | blockHash: BytesScalar 30 | ) { 31 | self.network = network 32 | self.blockHash = blockHash 33 | } 34 | 35 | /** 36 | - returns: 37 | `JSON` representation of the block 38 | 39 | - throws: 40 | `DescribedError` if something went wrong 41 | */ 42 | public func call() throws -> JSON { 43 | return try JSON( 44 | data: network.call( 45 | method: "eth_getBlockByHash", 46 | params: [ 47 | BytesParameter(bytes: blockHash), 48 | BooleanParameter(value: true) 49 | ] 50 | ) 51 | ) 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/CachedProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CachedProcedure.swift 7 | // 8 | // Created by Vadim Koleoshkin on 20/05/2019 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Permanently cached procedure */ 15 | public final class CachedProcedure: RemoteProcedure { 16 | 17 | private let stickyValue: StickyComputation 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - origin: procedure to cache 24 | */ 25 | public init(origin: RemoteProcedure) { 26 | self.stickyValue = StickyComputation{ 27 | try origin.call() 28 | } 29 | } 30 | 31 | /** 32 | - returns: 33 | Cashed `JSON` from the procedure 34 | 35 | - throws: 36 | `DescribedError` if something went wrong 37 | */ 38 | public func call() throws -> JSON { 39 | return try stickyValue.result() 40 | } 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/ChainIDProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ChainIDProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Identifier of the network */ 15 | public final class ChainIDProcedure: RemoteProcedure { 16 | 17 | private let network: Network 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - network: network to ask for identifier 24 | */ 25 | public init(network: Network) { 26 | self.network = network 27 | } 28 | 29 | /** 30 | - returns: 31 | `JSON` representation of the network id 32 | 33 | - throws: 34 | `DescribedError` if something went wrong 35 | */ 36 | public func call() throws -> JSON { 37 | return try JSON( 38 | data: network.call( 39 | method: "net_version", 40 | params: [] 41 | ) 42 | ) 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/ContractCallProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ContractCallProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** A call to the contract function */ 15 | final public class ContractCallProcedure: RemoteProcedure { 16 | 17 | private let network: Network 18 | private let parameters: [String: EthParameter] 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - network: network to call 25 | - parameters: parameters of the contract call 26 | */ 27 | public init( 28 | network: Network, 29 | parameters: [String: EthParameter] 30 | ) { 31 | self.network = network 32 | self.parameters = parameters 33 | } 34 | 35 | /** 36 | - returns: 37 | `JSON` for the call result 38 | 39 | - throws: 40 | `DescribedError` if something went wrong 41 | */ 42 | public func call() throws -> JSON { 43 | return try JSON( 44 | data: network.call( 45 | method: "eth_call", 46 | params: [ 47 | ObjectParameter( 48 | dictionary: parameters 49 | ), 50 | TagParameter( 51 | state: PendingBlockChainState() 52 | ) 53 | ] 54 | ) 55 | ) 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/EstimateGasProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EstimateGasProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | public final class EstimateGasProcedure: RemoteProcedure { 15 | 16 | private let network: Network 17 | private let parameters: [String: EthParameter] 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - network: network to call 24 | - parameters: arguments of the estimate 25 | */ 26 | public init( 27 | network: Network, 28 | parameters: [String: EthParameter] 29 | ) { 30 | self.network = network 31 | self.parameters = parameters 32 | } 33 | 34 | 35 | /** 36 | - returns: 37 | `JSON` for the gas estimate 38 | 39 | - throws: 40 | `DescribedError` if something went wrong 41 | */ 42 | public func call() throws -> JSON { 43 | return try JSON( 44 | data: network.call( 45 | method: "eth_estimateGas", 46 | params: [ 47 | ObjectParameter( 48 | dictionary: parameters 49 | ) 50 | ] 51 | ) 52 | ) 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/GetGasPriceProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // GetGasPriceProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | public class GetGasPriceProcedure: RemoteProcedure { 15 | 16 | private var network: Network 17 | 18 | public init(network: Network) { 19 | self.network = network 20 | } 21 | 22 | public func call() throws -> JSON { 23 | return try JSON( 24 | data: network.call( 25 | method: "eth_gasPrice", 26 | params: [] 27 | ) 28 | ) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/GetTransactionsCountProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // GetTransactionsCountProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | public class GetTransactionsCountProcedure: RemoteProcedure { 15 | 16 | private var network: Network 17 | private var address: BytesScalar 18 | private var blockChainState: BlockChainState 19 | 20 | public init(network: Network, address: BytesScalar, blockChainState: BlockChainState) { 21 | self.network = network 22 | self.address = address 23 | self.blockChainState = blockChainState 24 | } 25 | 26 | public func call() throws -> JSON { 27 | return try JSON( 28 | data: network.call( 29 | method: "eth_getTransactionCount", 30 | params: [ 31 | BytesParameter( 32 | bytes: address 33 | ), 34 | TagParameter(state: blockChainState) 35 | ] 36 | ) 37 | ) 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/JSONResultString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // JSONResultString.swift 7 | // 8 | // Created by Timofey Solonin on 25/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** "result" field as string of a json object */ 14 | public final class JSONResultString: StringScalar { 15 | 16 | private let json: RemoteProcedure 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - json: json containing string in a "result" field 23 | */ 24 | public init( 25 | json: RemoteProcedure 26 | ) { 27 | self.json = json 28 | } 29 | 30 | /** 31 | - returns: 32 | "result" field of a json as a string 33 | */ 34 | public func value() throws -> String { 35 | return try json.call()["result"].string() 36 | } 37 | 38 | } -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/RemoteProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // RemoteProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | public protocol RemoteProcedure { 15 | 16 | func call() throws -> JSON 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/SendRawTransactionProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SendRawTransactionProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Procedure for sending transaction bytes */ 15 | public final class SendRawTransactionProcedure: RemoteProcedure { 16 | 17 | private let network: Network 18 | private let transactionBytes: BytesScalar 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - network: network where to deploy transaction 25 | - transactionBytes: bytes of the transaction to be deployed 26 | */ 27 | public init( 28 | network: Network, 29 | transactionBytes: BytesScalar 30 | ) { 31 | self.network = network 32 | self.transactionBytes = transactionBytes 33 | } 34 | 35 | /** 36 | - returns: 37 | bytes representation of the `TransactionHash` 38 | 39 | - throws: 40 | `DescribedError` if something went wrong 41 | */ 42 | public func call() throws -> JSON { 43 | return try JSON( 44 | data: network.call( 45 | method: "eth_sendRawTransaction", 46 | params: [ 47 | BytesParameter(bytes: transactionBytes) 48 | ] 49 | ) 50 | ) 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/SimpleProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Anonymous procedure */ 15 | public final class SimpleProcedure: RemoteProcedure { 16 | 17 | private let json: () throws -> (JSON) 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - json: closure representation of a json returned by the `call` method 24 | */ 25 | public init(json: @escaping () throws -> (JSON)) { 26 | self.json = json 27 | } 28 | 29 | /** 30 | Ctor 31 | 32 | - parameters: 33 | - json: json returned by the `call` method 34 | */ 35 | public convenience init(json: JSON) { 36 | self.init(json: { json }) 37 | } 38 | 39 | /** 40 | - returns: 41 | `JSON` of the procedure 42 | 43 | - throws: 44 | `DescribedError` if something went wrong 45 | */ 46 | public func call() throws -> JSON { 47 | return try json() 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/TransactionProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TransactionProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Procedure for fetching transaction */ 15 | public final class TransactionProcedure: RemoteProcedure { 16 | 17 | private let network: Network 18 | private let transactionHash: BytesScalar 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - network: network to ask for transaction 25 | - transactionHash: hash of the raw transaction 26 | */ 27 | public init( 28 | network: Network, 29 | transactionHash: BytesScalar 30 | ) { 31 | self.network = network 32 | self.transactionHash = transactionHash 33 | } 34 | 35 | /** 36 | - returns: 37 | `JSON` representation of the transaction 38 | 39 | - throws: 40 | `DescribedError` if something went wrong 41 | */ 42 | public func call() throws -> JSON { 43 | return try JSON( 44 | data: network.call( 45 | method: "eth_getTransactionByHash", 46 | params: [ 47 | BytesParameter(bytes: transactionHash) 48 | ] 49 | ) 50 | ) 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /Web3Swift/RemoteProcedure/TransactionReceiptProcedure.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TransactionReceiptProcedure.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | /** Procedure for retrieving transaction receipt */ 15 | public final class TransactionReceiptProcedure: RemoteProcedure { 16 | 17 | private let transactionHash: BytesScalar 18 | private let network: Network 19 | 20 | /** 21 | Ctor 22 | 23 | - parameters: 24 | - network: network to ask for receipt 25 | - id: id of a receipt 26 | */ 27 | public init(network: Network, transactionHash: BytesScalar) { 28 | self.network = network 29 | self.transactionHash = transactionHash 30 | } 31 | 32 | /** 33 | - returns: 34 | `JSON` for the transaction receipt 35 | 36 | - throws: 37 | `DescribedError` if something went wrong 38 | */ 39 | public func call() throws -> JSON { 40 | return try JSON( 41 | data: network.call( 42 | method: "eth_getTransactionReceipt", 43 | params: [ 44 | BytesParameter(bytes: transactionHash) 45 | ] 46 | ) 47 | ) 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Web3Swift/SECP256k1/ECRecoverableSignature.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // ECRecoverableSignature.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Elliptic curve recoverable signature */ 14 | public protocol ECRecoverableSignature { 15 | 16 | /** 17 | R value as defined in ecdsa 18 | 19 | - returns: 20 | bytes representation 21 | 22 | - throws: 23 | `DescribedError` if something went wrong 24 | */ 25 | func r() throws -> BytesScalar 26 | 27 | /** 28 | S value as defined in ecdsa 29 | 30 | - returns: 31 | bytes representation 32 | 33 | - throws: 34 | `DescribedError` if something went wrong 35 | */ 36 | func s() throws -> BytesScalar 37 | 38 | /** 39 | Recovery id as defined in ecdsa 40 | 41 | - returns: 42 | a number 43 | 44 | - throws: 45 | `DescribedError` if something went wrong 46 | */ 47 | func recoverID() throws -> IntegerScalar 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/CompactHexString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // CompactHexString.swift 7 | // 8 | // Created by Vadim Koleoshkin on 16/06/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** A string that represents hexadecimal numbers in a compact way */ 14 | public final class CompactHexString: StringScalar { 15 | 16 | private let hex: StringScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - hex: a string describing a hexadecimal 23 | */ 24 | public init(hex: StringScalar) { 25 | self.hex = TrimmedPrefixString( 26 | string: UnprefixedHexString( 27 | hex: hex 28 | ), 29 | prefix: SimpleString( 30 | string: "0" 31 | ) 32 | ) 33 | } 34 | 35 | /** 36 | Ctor 37 | 38 | - parameters: 39 | - bytes: bytes of a hexadecimal 40 | */ 41 | public convenience init(bytes: BytesScalar) { 42 | self.init( 43 | hex: UnprefixedHexString( 44 | bytes: bytes 45 | ) 46 | ) 47 | } 48 | 49 | /** 50 | - returns: 51 | `String` representation of a string describing a hexadecimal 52 | 53 | - throws: 54 | `DescribedError` if something went wrong 55 | */ 56 | public func value() throws -> String { 57 | return try hex.value() 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/HexPrefix.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // HexPrefix.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just a hex perfix */ 14 | public final class HexPrefix: StringScalar { 15 | 16 | /** 17 | - returns: 18 | "0x" string 19 | 20 | - throws: 21 | doesn't throw 22 | */ 23 | public func value() throws -> String { 24 | return "0x" 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/HexPrefixedString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // HexPrefixedString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** String that is prefixed by 0x */ 14 | public final class HexPrefixedString: StringScalar { 15 | 16 | private let origin: StringScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - origin: string to be prefixed 23 | */ 24 | public init(origin: StringScalar) { 25 | self.origin = PrefixedString( 26 | origin: origin, 27 | prefix: HexPrefix() 28 | ) 29 | } 30 | 31 | /** 32 | - returns: 33 | String that is prefixed by 0x 34 | 35 | - throws: 36 | `DescribedError` if something went wrong 37 | */ 38 | public func value() throws -> String { 39 | return try origin.value() 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/PrefixedHexString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // PrefixedHexString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import CryptoSwift 12 | import Foundation 13 | 14 | /** Hex string that is prefixed by "0x" */ 15 | public final class PrefixedHexString: StringScalar { 16 | 17 | private let hex: StringScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - hex: a string describing a hexadecimal 24 | */ 25 | public init(hex: StringScalar) { 26 | self.hex = HexPrefixedString( 27 | origin: HexString( 28 | hex: hex 29 | ) 30 | ) 31 | } 32 | 33 | /** 34 | Ctor 35 | 36 | - parameters: 37 | - bytes: bytes of a hexadecimal 38 | */ 39 | public convenience init(bytes: BytesScalar) { 40 | self.init( 41 | hex: SimpleString{ 42 | try bytes.value().toHexString() 43 | } 44 | ) 45 | } 46 | 47 | /** 48 | - returns: 49 | Prefixed `String` representation of a hexadecimal 50 | 51 | - throws: 52 | `DescribedError` if something went wrong 53 | */ 54 | public func value() throws -> String { 55 | return try hex.value() 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/PrefixedString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // PrefixedString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** String that is prefixed */ 14 | public final class PrefixedString: StringScalar { 15 | 16 | private let origin: StringScalar 17 | private let prefix: StringScalar 18 | 19 | /** 20 | Ctor 21 | 22 | - parameters: 23 | - origin: origin to be prefixed 24 | - prefix: prefix to persist 25 | */ 26 | public init( 27 | origin: StringScalar, 28 | prefix: StringScalar 29 | ) { 30 | self.origin = origin 31 | self.prefix = prefix 32 | } 33 | 34 | /** 35 | - returns: 36 | `String` that is prefixed by the specified prefix if one doesn't exist 37 | 38 | - throws: 39 | `DescribedError` if something went wrong 40 | */ 41 | public func value() throws -> String { 42 | let origin = try self.origin.value() 43 | let prefix = try self.prefix.value() 44 | if origin.hasPrefix(prefix) { 45 | return origin 46 | } else { 47 | return "\(prefix)\(origin)" 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/SimpleString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // SimpleString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Anonymous string scalar wrapper */ 14 | public final class SimpleString: StringScalar { 15 | 16 | private let computation: () throws -> (String) 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - computation: computation that produces a `String` representation of a string 23 | */ 24 | public init(computation: @escaping () throws -> (String)) { 25 | self.computation = computation 26 | } 27 | 28 | /** 29 | Ctor 30 | 31 | - parameters: 32 | - string: `String` to be wrapped into scalar 33 | */ 34 | public convenience init(string: String) { 35 | self.init(computation: { string }) 36 | } 37 | 38 | /** 39 | - returns: 40 | `String` representation of a string scalar 41 | 42 | - throws: 43 | `DescribedError` if something went wrong 44 | */ 45 | public func value() throws -> String { 46 | return try computation() 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/StringScalar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // StringScalar.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Just a string */ 14 | public protocol StringScalar { 15 | 16 | /** 17 | - returns: 18 | Value of the string as `String` 19 | 20 | - throws: 21 | `DescribedError` if something went wrong 22 | */ 23 | func value() throws -> String 24 | 25 | } 26 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/UTF8String.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UTF8String.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import CryptoSwift 12 | import Foundation 13 | 14 | internal final class NotUTF8BytesError: DescribedError { 15 | 16 | private let bytes: Data 17 | public init(bytes: Data) { 18 | self.bytes = bytes 19 | } 20 | 21 | internal var description: String { 22 | return "Bytes 0x\(bytes.toHexString()) do not produce a valid utf8 string" 23 | } 24 | 25 | } 26 | 27 | /** utf8 string */ 28 | public final class UTF8String: StringScalar { 29 | 30 | private let bytes: BytesScalar 31 | /** 32 | Ctor 33 | 34 | - parameters: 35 | - bytes: bytes representation of a utf8 string 36 | */ 37 | public init(bytes: BytesScalar) { 38 | self.bytes = bytes 39 | } 40 | 41 | /** 42 | - returns: 43 | UTF8 encoded string 44 | 45 | - throws: 46 | `DescribedError` if something went wrong. I.e. if string was not utf8 47 | */ 48 | public func value() throws -> String { 49 | let bytes = try self.bytes.value() 50 | guard let value = String( 51 | bytes: bytes, 52 | encoding: String.Encoding.utf8 53 | ) else { 54 | throw NotUTF8BytesError( 55 | bytes: bytes 56 | ) 57 | } 58 | return value 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /Web3Swift/StringScalar/UnprefixedHexString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // UnprefixedHexString.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Hex string that is not prefixed by "0x" */ 14 | public final class UnprefixedHexString: StringScalar { 15 | 16 | private let hex: StringScalar 17 | 18 | /** 19 | Ctor 20 | 21 | - parameters: 22 | - hex: a string describing a hexadecimal 23 | */ 24 | public init(hex: StringScalar) { 25 | self.hex = TrimmedPrefixString( 26 | string: HexString(hex: hex), 27 | prefix: HexPrefix() 28 | ) 29 | } 30 | 31 | /** 32 | Ctor 33 | 34 | - parameters: 35 | - bytes: bytes of a hexadecimal 36 | */ 37 | public convenience init(bytes: BytesScalar) { 38 | self.init( 39 | hex: SimpleString{ 40 | try bytes.value().toHexString() 41 | } 42 | ) 43 | } 44 | 45 | /** 46 | - returns: 47 | Unprefixed `String` representation of a hexadecimal 48 | 49 | - throws: 50 | `DescribedError` if something went wrong 51 | */ 52 | public func value() throws -> String { 53 | return try hex.value() 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /Web3Swift/Transaction/Transaction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Transaction.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | //FIXME: Not full implementation of transaction 15 | /** A transaction from the blockchain */ 16 | public protocol Transaction { 17 | /** 18 | - returns: 19 | Number of transactions deployed by sender before this one 20 | 21 | - throws: 22 | `DescribedError` if something went wrong 23 | */ 24 | func nonce() throws -> BytesScalar 25 | 26 | func blockHash() throws -> BlockHash 27 | 28 | func from() throws -> EthAddress 29 | 30 | func gas() throws -> EthNumber 31 | 32 | func gasPrice() throws -> EthNumber 33 | 34 | func hash() throws -> TransactionHash 35 | 36 | func input() throws -> BytesScalar 37 | 38 | func to() throws -> EthAddress 39 | 40 | func value() throws -> EthNumber 41 | } 42 | -------------------------------------------------------------------------------- /Web3Swift/TransactionHash/TransactionHash.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TransactionHash.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Hash of a raw transaction data */ 14 | public protocol TransactionHash: BytesScalar { 15 | 16 | /** 17 | - returns: 18 | `Transaction` that is associated with the hash 19 | 20 | - throws: 21 | `DescribedError if something went wrong` 22 | */ 23 | func transaction() throws -> Transaction 24 | 25 | /** 26 | - returns: 27 | `TransactionReceipt` that is associated with the hash 28 | 29 | - throws: 30 | `DescribedError if something went wrong` 31 | */ 32 | func receipt() throws -> TransactionReceipt 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Web3Swift/TransactionLogs/TransactionLog.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2019 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TransactionLog.swift 7 | // 8 | // Created by Vadim Koleoshkin on 14/05/2019 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol TransactionLog { 14 | 15 | func signature() throws -> BytesScalar 16 | 17 | func topics() throws -> [BytesScalar] 18 | 19 | func data() throws -> ABIMessage 20 | 21 | func index() throws -> EthNumber 22 | 23 | func removed() throws -> BooleanScalar 24 | 25 | func address() throws -> EthAddress 26 | 27 | func transactionHash() throws -> TransactionHash 28 | 29 | func blockHash() throws -> BlockHash 30 | 31 | func blockNumber() throws -> EthNumber 32 | 33 | func transactionIndex() throws -> EthNumber 34 | 35 | } 36 | -------------------------------------------------------------------------------- /Web3Swift/TransactionReceipt/TransactionReceipt.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TransactionReceipt.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | /** Receipt associated with the transaction */ 14 | public protocol TransactionReceipt { 15 | 16 | func blockHash() throws -> BlockHash 17 | 18 | func cumulativeUsedGasAmount() throws -> EthNumber 19 | 20 | /** 21 | - returns: 22 | Gas amount that was used up by the transaction 23 | 24 | - throws: 25 | `DescribedError if something went wrong` 26 | */ 27 | func usedGasAmount() throws -> BytesScalar 28 | 29 | /** 30 | - returns: 31 | Collection of logs emmited in transaction 32 | 33 | - throws: 34 | `DescribedError if something went wrong` 35 | */ 36 | func logs() throws -> CollectionScalar 37 | 38 | } 39 | -------------------------------------------------------------------------------- /Web3Swift/Transactions/EthTransactions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // EthTransactions.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | import SwiftyJSON 13 | 14 | public final class EthTransactions: Transactions { 15 | 16 | private let procedure: RemoteProcedure 17 | public init(network: Network, address: BytesScalar, blockChainState: BlockChainState) { 18 | self.procedure = GetTransactionsCountProcedure( 19 | network: network, 20 | address: address, 21 | blockChainState: blockChainState 22 | ) 23 | } 24 | 25 | public func count() throws -> BytesScalar { 26 | let transactionsCountProcedure = self.procedure 27 | return EthNumber( 28 | hex: SimpleString{ 29 | try transactionsCountProcedure.call()["result"].string() 30 | } 31 | ) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Web3Swift/Transactions/Transactions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // Transactions.swift 7 | // 8 | // Created by Timofey Solonin on 10/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public protocol Transactions { 14 | 15 | func count() throws -> BytesScalar 16 | 17 | } 18 | -------------------------------------------------------------------------------- /Web3Swift/Transactions/TransactionsCount.swift: -------------------------------------------------------------------------------- 1 | // 2 | // This source file is part of the Web3Swift.io open source project 3 | // Copyright 2018 The Web3Swift Authors 4 | // Licensed under Apache License v2.0 5 | // 6 | // TransactionsCount.swift 7 | // 8 | // Created by Timofey Solonin on 16/05/2018 9 | // 10 | 11 | import Foundation 12 | 13 | public final class TransactionsCount: BytesScalar { 14 | 15 | private let transactions: Transactions 16 | public init(transactions: Transactions) { 17 | self.transactions = transactions 18 | } 19 | 20 | public func value() throws -> Data { 21 | return try transactions.count().value() 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj -------------------------------------------------------------------------------- /buddybuild_postclone.sh: -------------------------------------------------------------------------------- 1 | yarn install 2 | screen -S unittest-api -d -m bash -c "yarn run ganache-cli --account="0x1636e10756e62baabddd4364010444205f1216bdb1644ff8f776f6e2982aa9f5,1000000000000000000" --account="0x159b7c413354adec1bd31caaf7e4fde71e9132a5b29193d2f6181de777745493,1000000000000000000" --account="0x4836d1e4785f62498ec6a7a61ff0d01e3fa97dba863a76f5a6c3ace47f62be3f,100000000000000000000" --gasPrice="20000000000" --networkId="1"" -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | ignore: 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Web3SwiftGanacheDeps", 3 | "version": "0.0.1.", 4 | "description": "Web3Swift test net dependencies", 5 | "author": "Web3Swift", 6 | "license": "Apache License 2.0", 7 | "private": true, 8 | "engines": { 9 | "yarn": "^1.2.1" 10 | }, 11 | "dependencies": { 12 | "bignumber.js": "^6.0.0", 13 | "ganache-cli": "^6.0.3", 14 | "truffle": "^4.0.6" 15 | } 16 | } 17 | --------------------------------------------------------------------------------