Repository: SteadyAction/EtherWalletKit Branch: develop Commit: 3962c14ecf57 Files: 30 Total size: 76.0 KB Directory structure: gitextract_ee0jz0ij/ ├── .gitignore ├── Docs/ │ └── Document.md ├── EtherWalletKit.podspec ├── EtherWalletKit.xcodeproj/ │ ├── EtherWalletKitTests_Info.plist │ ├── EtherWalletKit_Info.plist │ ├── project.pbxproj │ ├── project.xcworkspace/ │ │ └── contents.xcworkspacedata │ └── xcshareddata/ │ └── xcschemes/ │ ├── EtherWalletKit-Package.xcscheme │ └── xcschememanagement.plist ├── EtherWalletKit.xcworkspace/ │ ├── contents.xcworkspacedata │ └── xcshareddata/ │ └── IDEWorkspaceChecks.plist ├── EtherWalletKitTest/ │ ├── EtherWalletKitTest.swift │ └── Info.plist ├── LICENSE ├── Package.swift ├── Podfile ├── README.md └── Sources/ ├── Structure/ │ ├── EtherscanAPIResponse.swift │ ├── EthplorerAPIResponse.swift │ ├── GasStationAPIResponse.swift │ └── TransactionData.swift └── Wallet/ ├── EtherWallet+Account.swift ├── EtherWallet+Balance.swift ├── EtherWallet+History.swift ├── EtherWallet+Info.swift ├── EtherWallet+Transaction.swift ├── EtherWallet+Util.swift ├── EtherWallet.swift ├── EtherWalletTestnets.swift └── WalletError.swift ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store /.build /Packages *.xcuserstate xcuserdata/ Pods/ ================================================ FILE: Docs/Document.md ================================================ ## Getting Started #### 0. Don't forget to import it ``` swift import EtherWalletKit ``` #### Mainet or Testnet(Rinkeby) If you want to work on the testnet(Rinkeby), use `EtherWalletRinkeby` instead of `EtherWallet`. #### Create an Ethereum Wallet ```swift // Generate a new account with its new password. try? EtherWallet.account.generateAccount(password: "ABCDEFG") // Import an existing account from its private key and set its new password. try? EtherWallet.account.importAccount(privateKey: "1dcbc1d6e0a4587a3a9095984cf051a1bc6ed975f15380a0ac97f01c0c045062, password: "ABCDEFG") ``` Note: ```password``` will be encrypted and saved to the device and it will be required to access the wallet. #### Get account information ```swift // Get address of your account let address = EtherWallet.account.address // Get private key of your account let privateKey = try! EtherWallet.account.privateKey(password: "ABCDEFG") ``` #### Get balance ```swift // Get balance of Ether EtherWallet.balance.etherBalance { balance in print(balance) } // Get balance of a token EtherWallet.balance.tokenBalance(contractAddress: "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07") { balance in print(balance) } ``` #### Send ```swift // send Ether to an address. EtherWallet.transaction.sendEther(to: "0x7777787C97a35d37Db8E5afb0C92BCfd4F6480bE", amount: "1.5", password: "ABCDEFG") { txHash in print(txHash) } // send a token to an address. EtherWallet.transaction.sendToken(to: "0x7777787C97a35d37Db8E5afb0C92BCfd4F6480bE", contractAddress: "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07", amount: "20", password: "ABCDEFG", decimal: 18) { txHash in print(txHash) } ``` Note: ```password``` should be eqaul to the password of wallet created. Also you can put ```gasPrice``` as an extra parameter to set gas price for the transcation. ================================================ FILE: EtherWalletKit.podspec ================================================ # # Be sure to run `pod lib lint EtherWalletKit.podspec' to ensure this is a # valid spec before submitting. # # Any lines starting with a # are optional, but their use is encouraged # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html # Pod::Spec.new do |s| s.name = 'EtherWalletKit' s.version = '0.1.4' s.summary = 'Ethereum Wallet Toolkit for iOS' s.swift_version = '4.0' # This description is used to generate tags and improve search results. # * Think: What does it do? Why did you write it? What is the focus? # * Try to keep it short, snappy and to the point. # * Write the description between the DESC delimiters below. # * Finally, don't worry about the indent, CocoaPods strips it! s.description = <<-DESC Ethereum Wallet Toolkit for iOS - You can implement Ethereum wallet without a server and blockchain knowledge. DESC s.homepage = 'https://github.com/SteadyAction/EtherWalletKit' # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = { 'SteadyAction' => 'steadyaction@gmail.com' } s.source = { :git => 'https://github.com/SteadyAction/EtherWalletKit.git', :tag => s.version.to_s } # s.social_media_url = 'https://twitter.com/' s.ios.deployment_target = '10.0' s.source_files = 'Sources/**/*' # s.resource_bundles = { # 'EtherWalletKit' => ['EtherWalletKit/Assets/*.png'] # } # s.public_header_files = 'Pod/Classes/**/*.h' # s.frameworks = 'UIKit', 'MapKit' s.dependency 'web3swift', '~> 2.0' s.dependency 'SwiftKeychainWrapper' end ================================================ FILE: EtherWalletKit.xcodeproj/EtherWalletKitTests_Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass ================================================ FILE: EtherWalletKit.xcodeproj/EtherWalletKit_Info.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass ================================================ FILE: EtherWalletKit.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXAggregateTarget section */ EtherWalletKit::EtherWalletKitPackageTests::ProductTarget /* EtherWalletKitPackageTests */ = { isa = PBXAggregateTarget; buildConfigurationList = OBJ_31 /* Build configuration list for PBXAggregateTarget "EtherWalletKitPackageTests" */; buildPhases = ( ); dependencies = ( OBJ_34 /* PBXTargetDependency */, ); name = EtherWalletKitPackageTests; productName = EtherWalletKitPackageTests; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 1EDFEC0DB3B02D59F8E546BB /* Pods_EtherWalletKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CF04867D39E0379185470242 /* Pods_EtherWalletKit.framework */; }; E4746BA3B4CE720D158512A1 /* Pods_EtherWalletKitTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D808C8FA634AFA1C9EA96F19 /* Pods_EtherWalletKitTest.framework */; }; E83118B620F3391E00FF3CCC /* EtherWallet+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83118B520F3391E00FF3CCC /* EtherWallet+Account.swift */; }; E83118BA20F33BCA00FF3CCC /* EtherWallet+Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83118B920F33BC900FF3CCC /* EtherWallet+Balance.swift */; }; E83118C120F4523D00FF3CCC /* EtherWallet+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83118C020F4523A00FF3CCC /* EtherWallet+Transaction.swift */; }; E83C24A120E399B0005645EF /* EtherWallet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83C24A020E399B0005645EF /* EtherWallet.swift */; }; E83C24AB20E39BE6005645EF /* EtherscanAPIResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83C24AA20E39BE6005645EF /* EtherscanAPIResponse.swift */; }; E83C24AF20E39C2F005645EF /* TransactionData.swift in Sources */ = {isa = PBXBuildFile; fileRef = E83C24AE20E39C2F005645EF /* TransactionData.swift */; }; E849CEBA20EB1D0700F38B76 /* GasStationAPIResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = E849CEB920EB1D0700F38B76 /* GasStationAPIResponse.swift */; }; E849CEBC20EB4BA200F38B76 /* EthplorerAPIResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = E849CEBB20EB4BA200F38B76 /* EthplorerAPIResponse.swift */; }; E849CEBE20EB5C3B00F38B76 /* WalletError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E849CEBD20EB5C3B00F38B76 /* WalletError.swift */; }; E86669C621024E1200F99335 /* EtherWallet+Util.swift in Sources */ = {isa = PBXBuildFile; fileRef = E86669C521024E1200F99335 /* EtherWallet+Util.swift */; }; E8B4753B21002C98004B65E9 /* EtherWallet+Info.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8B4753A21002C98004B65E9 /* EtherWallet+Info.swift */; }; E8CB3D7821043E8D00AC6A14 /* EtherWallet+History.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8CB3D7721043E8D00AC6A14 /* EtherWallet+History.swift */; }; E8D4CF342109CCB4008476B8 /* EtherWalletTestnets.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8D4CF332109CCB4008476B8 /* EtherWalletTestnets.swift */; }; E8D4CF3E2109F07D008476B8 /* EtherWalletKitTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = E8D4CF3D2109F07D008476B8 /* EtherWalletKitTest.swift */; }; OBJ_29 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; }; OBJ_43 /* EtherWalletKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EtherWalletKit::EtherWalletKit::Product /* EtherWalletKit.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ E8665C8320E3939600F4AD19 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = OBJ_1 /* Project object */; proxyType = 1; remoteGlobalIDString = "EtherWalletKit::EtherWalletKit"; remoteInfo = EtherWalletKit; }; E8665C8420E3939A00F4AD19 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = OBJ_1 /* Project object */; proxyType = 1; remoteGlobalIDString = "EtherWalletKit::EtherWalletKitTests"; remoteInfo = EtherWalletKitTests; }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ E8CA9E4F2109FC0600F48458 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ 20E55D35F58BE23153B75758 /* Pods-EtherWalletKit.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EtherWalletKit.debug.xcconfig"; path = "Pods/Target Support Files/Pods-EtherWalletKit/Pods-EtherWalletKit.debug.xcconfig"; sourceTree = ""; }; 29F409A933CCEC902753AC43 /* Pods_EtherWalletKit_EtherWalletKitTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EtherWalletKit_EtherWalletKitTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 58BEAAFE6E50744CCC966592 /* Pods-EtherWalletKit.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EtherWalletKit.release.xcconfig"; path = "Pods/Target Support Files/Pods-EtherWalletKit/Pods-EtherWalletKit.release.xcconfig"; sourceTree = ""; }; 6049B9E4E2D438BB6F94139B /* Pods-EtherWalletKit-EtherWalletKitTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EtherWalletKit-EtherWalletKitTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-EtherWalletKit-EtherWalletKitTest/Pods-EtherWalletKit-EtherWalletKitTest.debug.xcconfig"; sourceTree = ""; }; 63C3EA9E421DCB0B6F2524FD /* Pods-EtherWalletKitTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EtherWalletKitTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-EtherWalletKitTest/Pods-EtherWalletKitTest.release.xcconfig"; sourceTree = ""; }; 74D93172CB9698EEC90AF45E /* Pods-EtherWalletKitTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EtherWalletKitTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-EtherWalletKitTest/Pods-EtherWalletKitTest.debug.xcconfig"; sourceTree = ""; }; CF04867D39E0379185470242 /* Pods_EtherWalletKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EtherWalletKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D808C8FA634AFA1C9EA96F19 /* Pods_EtherWalletKitTest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EtherWalletKitTest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E3051174CD82B2B4C9FA3E45 /* Pods-EtherWalletKit-EtherWalletKitTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EtherWalletKit-EtherWalletKitTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-EtherWalletKit-EtherWalletKitTest/Pods-EtherWalletKit-EtherWalletKitTest.release.xcconfig"; sourceTree = ""; }; E83118B520F3391E00FF3CCC /* EtherWallet+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EtherWallet+Account.swift"; sourceTree = ""; }; E83118B920F33BC900FF3CCC /* EtherWallet+Balance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EtherWallet+Balance.swift"; sourceTree = ""; }; E83118C020F4523A00FF3CCC /* EtherWallet+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EtherWallet+Transaction.swift"; sourceTree = ""; }; E83C24A020E399B0005645EF /* EtherWallet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EtherWallet.swift; sourceTree = ""; }; E83C24AA20E39BE6005645EF /* EtherscanAPIResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EtherscanAPIResponse.swift; sourceTree = ""; }; E83C24AE20E39C2F005645EF /* TransactionData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransactionData.swift; sourceTree = ""; }; E849CEB920EB1D0700F38B76 /* GasStationAPIResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GasStationAPIResponse.swift; sourceTree = ""; }; E849CEBB20EB4BA200F38B76 /* EthplorerAPIResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthplorerAPIResponse.swift; sourceTree = ""; }; E849CEBD20EB5C3B00F38B76 /* WalletError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletError.swift; sourceTree = ""; }; E8665C8520E394CF00F4AD19 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; E8665C8620E394CF00F4AD19 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; E8665C8720E394CF00F4AD19 /* EtherWalletKit.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = EtherWalletKit.podspec; sourceTree = ""; }; E86669C521024E1200F99335 /* EtherWallet+Util.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EtherWallet+Util.swift"; sourceTree = ""; }; E8B4753A21002C98004B65E9 /* EtherWallet+Info.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EtherWallet+Info.swift"; sourceTree = ""; }; E8CB3D7721043E8D00AC6A14 /* EtherWallet+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EtherWallet+History.swift"; sourceTree = ""; }; E8D4CF332109CCB4008476B8 /* EtherWalletTestnets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EtherWalletTestnets.swift; sourceTree = ""; }; E8D4CF362109E66D008476B8 /* Document.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Document.md; sourceTree = ""; }; E8D4CF3B2109F07D008476B8 /* EtherWalletKitTest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EtherWalletKitTest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; E8D4CF3D2109F07D008476B8 /* EtherWalletKitTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EtherWalletKitTest.swift; sourceTree = ""; }; E8D4CF3F2109F07D008476B8 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; EtherWalletKit::EtherWalletKit::Product /* EtherWalletKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = EtherWalletKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; EtherWalletKit::EtherWalletKitTests::Product /* EtherWalletKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = EtherWalletKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 23A961ACB3F6BDC02E74968E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; E8D4CF382109F07D008476B8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( E4746BA3B4CE720D158512A1 /* Pods_EtherWalletKitTest.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; OBJ_23 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 0; files = ( 1EDFEC0DB3B02D59F8E546BB /* Pods_EtherWalletKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; OBJ_42 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 0; files = ( OBJ_43 /* EtherWalletKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 287731197E01E164172DCDF5 /* Frameworks */ = { isa = PBXGroup; children = ( CF04867D39E0379185470242 /* Pods_EtherWalletKit.framework */, 29F409A933CCEC902753AC43 /* Pods_EtherWalletKit_EtherWalletKitTest.framework */, D808C8FA634AFA1C9EA96F19 /* Pods_EtherWalletKitTest.framework */, ); name = Frameworks; sourceTree = ""; }; 83A5C5AAC8028885D5C13320 /* Pods */ = { isa = PBXGroup; children = ( 20E55D35F58BE23153B75758 /* Pods-EtherWalletKit.debug.xcconfig */, 58BEAAFE6E50744CCC966592 /* Pods-EtherWalletKit.release.xcconfig */, 6049B9E4E2D438BB6F94139B /* Pods-EtherWalletKit-EtherWalletKitTest.debug.xcconfig */, E3051174CD82B2B4C9FA3E45 /* Pods-EtherWalletKit-EtherWalletKitTest.release.xcconfig */, 74D93172CB9698EEC90AF45E /* Pods-EtherWalletKitTest.debug.xcconfig */, 63C3EA9E421DCB0B6F2524FD /* Pods-EtherWalletKitTest.release.xcconfig */, ); name = Pods; sourceTree = ""; }; E83C249E20E399B0005645EF /* Sources */ = { isa = PBXGroup; children = ( E849CEB820EB19C200F38B76 /* Structure */, E83C249F20E399B0005645EF /* Wallet */, ); path = Sources; sourceTree = ""; }; E83C249F20E399B0005645EF /* Wallet */ = { isa = PBXGroup; children = ( E83C24A020E399B0005645EF /* EtherWallet.swift */, E83118B520F3391E00FF3CCC /* EtherWallet+Account.swift */, E83118B920F33BC900FF3CCC /* EtherWallet+Balance.swift */, E83118C020F4523A00FF3CCC /* EtherWallet+Transaction.swift */, E8B4753A21002C98004B65E9 /* EtherWallet+Info.swift */, E8CB3D7721043E8D00AC6A14 /* EtherWallet+History.swift */, E86669C521024E1200F99335 /* EtherWallet+Util.swift */, E8D4CF332109CCB4008476B8 /* EtherWalletTestnets.swift */, E849CEBD20EB5C3B00F38B76 /* WalletError.swift */, ); path = Wallet; sourceTree = ""; }; E849CEB820EB19C200F38B76 /* Structure */ = { isa = PBXGroup; children = ( E83C24AA20E39BE6005645EF /* EtherscanAPIResponse.swift */, E849CEB920EB1D0700F38B76 /* GasStationAPIResponse.swift */, E849CEBB20EB4BA200F38B76 /* EthplorerAPIResponse.swift */, E83C24AE20E39C2F005645EF /* TransactionData.swift */, ); path = Structure; sourceTree = ""; }; E8D4CF352109E66D008476B8 /* Docs */ = { isa = PBXGroup; children = ( E8D4CF362109E66D008476B8 /* Document.md */, ); path = Docs; sourceTree = ""; }; E8D4CF3C2109F07D008476B8 /* EtherWalletKitTest */ = { isa = PBXGroup; children = ( E8D4CF3D2109F07D008476B8 /* EtherWalletKitTest.swift */, E8D4CF3F2109F07D008476B8 /* Info.plist */, ); path = EtherWalletKitTest; sourceTree = ""; }; OBJ_14 /* Products */ = { isa = PBXGroup; children = ( EtherWalletKit::EtherWalletKitTests::Product /* EtherWalletKitTests.xctest */, EtherWalletKit::EtherWalletKit::Product /* EtherWalletKit.framework */, E8D4CF3B2109F07D008476B8 /* EtherWalletKitTest.xctest */, ); name = Products; sourceTree = BUILT_PRODUCTS_DIR; }; OBJ_5 = { isa = PBXGroup; children = ( OBJ_6 /* Package.swift */, E8665C8720E394CF00F4AD19 /* EtherWalletKit.podspec */, E8665C8520E394CF00F4AD19 /* LICENSE */, E8665C8620E394CF00F4AD19 /* README.md */, E83C249E20E399B0005645EF /* Sources */, E8D4CF352109E66D008476B8 /* Docs */, E8D4CF3C2109F07D008476B8 /* EtherWalletKitTest */, OBJ_14 /* Products */, 83A5C5AAC8028885D5C13320 /* Pods */, 287731197E01E164172DCDF5 /* Frameworks */, ); sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ E8D4CF3A2109F07D008476B8 /* EtherWalletKitTest */ = { isa = PBXNativeTarget; buildConfigurationList = E8D4CF402109F07D008476B8 /* Build configuration list for PBXNativeTarget "EtherWalletKitTest" */; buildPhases = ( BB104CFDCBEFDE4B9B23AA5A /* [CP] Check Pods Manifest.lock */, E8D4CF372109F07D008476B8 /* Sources */, E8D4CF382109F07D008476B8 /* Frameworks */, E8D4CF392109F07D008476B8 /* Resources */, E8CA9E4F2109FC0600F48458 /* CopyFiles */, D62F1E8A6BB12A40C37E82EC /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( ); name = EtherWalletKitTest; productName = EtherWalletKitTest; productReference = E8D4CF3B2109F07D008476B8 /* EtherWalletKitTest.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; EtherWalletKit::EtherWalletKit /* EtherWalletKit */ = { isa = PBXNativeTarget; buildConfigurationList = OBJ_18 /* Build configuration list for PBXNativeTarget "EtherWalletKit" */; buildPhases = ( 7ABA8827529429D5C2B7EEF4 /* [CP] Check Pods Manifest.lock */, OBJ_21 /* Sources */, OBJ_23 /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = EtherWalletKit; productName = EtherWalletKit; productReference = EtherWalletKit::EtherWalletKit::Product /* EtherWalletKit.framework */; productType = "com.apple.product-type.framework"; }; EtherWalletKit::EtherWalletKitTests /* EtherWalletKitTests */ = { isa = PBXNativeTarget; buildConfigurationList = OBJ_36 /* Build configuration list for PBXNativeTarget "EtherWalletKitTests" */; buildPhases = ( OBJ_39 /* Sources */, OBJ_42 /* Frameworks */, ); buildRules = ( ); dependencies = ( OBJ_44 /* PBXTargetDependency */, ); name = EtherWalletKitTests; productName = EtherWalletKitTests; productReference = EtherWalletKit::EtherWalletKitTests::Product /* EtherWalletKitTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; EtherWalletKit::SwiftPMPackageDescription /* EtherWalletKitPackageDescription */ = { isa = PBXNativeTarget; buildConfigurationList = OBJ_25 /* Build configuration list for PBXNativeTarget "EtherWalletKitPackageDescription" */; buildPhases = ( OBJ_28 /* Sources */, 23A961ACB3F6BDC02E74968E /* Frameworks */, ); buildRules = ( ); dependencies = ( ); name = EtherWalletKitPackageDescription; productName = EtherWalletKitPackageDescription; productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ OBJ_1 /* Project object */ = { isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0940; LastUpgradeCheck = 9999; TargetAttributes = { E8D4CF3A2109F07D008476B8 = { CreatedOnToolsVersion = 9.4.1; DevelopmentTeam = T4C6698GAN; ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "EtherWalletKit" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); mainGroup = OBJ_5; productRefGroup = OBJ_14 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( EtherWalletKit::EtherWalletKit /* EtherWalletKit */, EtherWalletKit::SwiftPMPackageDescription /* EtherWalletKitPackageDescription */, EtherWalletKit::EtherWalletKitPackageTests::ProductTarget /* EtherWalletKitPackageTests */, EtherWalletKit::EtherWalletKitTests /* EtherWalletKitTests */, E8D4CF3A2109F07D008476B8 /* EtherWalletKitTest */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ E8D4CF392109F07D008476B8 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ 7ABA8827529429D5C2B7EEF4 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-EtherWalletKit-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; BB104CFDCBEFDE4B9B23AA5A /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-EtherWalletKitTest-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; D62F1E8A6BB12A40C37E82EC /* [CP] Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "${SRCROOT}/Pods/Target Support Files/Pods-EtherWalletKitTest/Pods-EtherWalletKitTest-frameworks.sh", "${BUILT_PRODUCTS_DIR}/BigInt-iOS11.4/BigInt.framework", "${BUILT_PRODUCTS_DIR}/CryptoSwift-iOS11.4/CryptoSwift.framework", "${BUILT_PRODUCTS_DIR}/EthereumABI-iOS11.4/EthereumABI.framework", "${BUILT_PRODUCTS_DIR}/EthereumAddress-iOS11.4/EthereumAddress.framework", "${BUILT_PRODUCTS_DIR}/PromiseKit-iOS11.4/PromiseKit.framework", "${BUILT_PRODUCTS_DIR}/SipHash-iOS11.4/SipHash.framework", "${BUILT_PRODUCTS_DIR}/SwiftRLP-iOS11.4/SwiftRLP.framework", "${BUILT_PRODUCTS_DIR}/scrypt-iOS11.4/scrypt.framework", "${BUILT_PRODUCTS_DIR}/secp256k1_swift-iOS11.4/secp256k1_swift.framework", "${BUILT_PRODUCTS_DIR}/web3swift-iOS11.4/Web3swift.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BigInt.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CryptoSwift.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EthereumABI.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EthereumAddress.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PromiseKit.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SipHash.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftRLP.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/scrypt.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/secp256k1_swift.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Web3swift.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-EtherWalletKitTest/Pods-EtherWalletKitTest-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ E8D4CF372109F07D008476B8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( E8D4CF3E2109F07D008476B8 /* EtherWalletKitTest.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; OBJ_21 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( E83C24A120E399B0005645EF /* EtherWallet.swift in Sources */, E83C24AF20E39C2F005645EF /* TransactionData.swift in Sources */, E86669C621024E1200F99335 /* EtherWallet+Util.swift in Sources */, E849CEBA20EB1D0700F38B76 /* GasStationAPIResponse.swift in Sources */, E849CEBE20EB5C3B00F38B76 /* WalletError.swift in Sources */, E83118C120F4523D00FF3CCC /* EtherWallet+Transaction.swift in Sources */, E83118B620F3391E00FF3CCC /* EtherWallet+Account.swift in Sources */, E849CEBC20EB4BA200F38B76 /* EthplorerAPIResponse.swift in Sources */, E83118BA20F33BCA00FF3CCC /* EtherWallet+Balance.swift in Sources */, E83C24AB20E39BE6005645EF /* EtherscanAPIResponse.swift in Sources */, E8CB3D7821043E8D00AC6A14 /* EtherWallet+History.swift in Sources */, E8D4CF342109CCB4008476B8 /* EtherWalletTestnets.swift in Sources */, E8B4753B21002C98004B65E9 /* EtherWallet+Info.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; OBJ_28 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( OBJ_29 /* Package.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; OBJ_39 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 0; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ OBJ_34 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EtherWalletKit::EtherWalletKitTests /* EtherWalletKitTests */; targetProxy = E8665C8420E3939A00F4AD19 /* PBXContainerItemProxy */; }; OBJ_44 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EtherWalletKit::EtherWalletKit /* EtherWalletKit */; targetProxy = E8665C8320E3939600F4AD19 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ E8D4CF412109F07D008476B8 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 74D93172CB9698EEC90AF45E /* Pods-EtherWalletKitTest.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; DEVELOPMENT_TEAM = T4C6698GAN; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = EtherWalletKitTest/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.4; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.SteadyAction.EtherWalletKitTest; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; E8D4CF422109F07D008476B8 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 63C3EA9E421DCB0B6F2524FD /* Pods-EtherWalletKitTest.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; COPY_PHASE_STRIP = NO; DEVELOPMENT_TEAM = T4C6698GAN; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; INFOPLIST_FILE = EtherWalletKitTest/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.4; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.SteadyAction.EtherWalletKitTest; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = iphoneos; SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; name = Release; }; OBJ_19 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 20E55D35F58BE23153B75758 /* Pods-EtherWalletKit.debug.xcconfig */; buildSettings = { ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = EtherWalletKit.xcodeproj/EtherWalletKit_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = EtherWalletKit; PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; SWIFT_VERSION = 4.0; TARGET_NAME = EtherWalletKit; }; name = Debug; }; OBJ_20 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 58BEAAFE6E50744CCC966592 /* Pods-EtherWalletKit.release.xcconfig */; buildSettings = { ENABLE_TESTABILITY = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = EtherWalletKit.xcodeproj/EtherWalletKit_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) $(TOOLCHAIN_DIR)/usr/lib/swift/macosx"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = EtherWalletKit; PRODUCT_MODULE_NAME = "$(TARGET_NAME:c99extidentifier)"; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; SWIFT_VERSION = 4.0; TARGET_NAME = EtherWalletKit; }; name = Release; }; OBJ_26 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { LD = /usr/bin/true; OTHER_SWIFT_FLAGS = "-swift-version 4 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk"; SWIFT_VERSION = 4.0; }; name = Debug; }; OBJ_27 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { LD = /usr/bin/true; OTHER_SWIFT_FLAGS = "-swift-version 4 -I $(TOOLCHAIN_DIR)/usr/lib/swift/pm/4 -target x86_64-apple-macosx10.10 -sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk"; SWIFT_VERSION = 4.0; }; name = Release; }; OBJ_3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; DYLIB_INSTALL_NAME_BASE = "@rpath"; ENABLE_NS_ASSERTIONS = YES; GCC_OPTIMIZATION_LEVEL = 0; MACOSX_DEPLOYMENT_TARGET = 10.10; ONLY_ACTIVE_ARCH = YES; OTHER_SWIFT_FLAGS = "-DXcode"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; USE_HEADERMAP = NO; }; name = Debug; }; OBJ_32 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Debug; }; OBJ_33 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { }; name = Release; }; OBJ_37 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = EtherWalletKit.xcodeproj/EtherWalletKitTests_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)"; SWIFT_VERSION = 4.0; TARGET_NAME = EtherWalletKitTests; }; name = Debug; }; OBJ_38 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PLATFORM_DIR)/Developer/Library/Frameworks", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = EtherWalletKit.xcodeproj/EtherWalletKitTests_Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @loader_path/../Frameworks @loader_path/Frameworks"; OTHER_CFLAGS = "$(inherited)"; OTHER_LDFLAGS = "$(inherited)"; OTHER_SWIFT_FLAGS = "$(inherited)"; SWIFT_VERSION = 4.0; TARGET_NAME = EtherWalletKitTests; }; name = Release; }; OBJ_4 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DYLIB_INSTALL_NAME_BASE = "@rpath"; GCC_OPTIMIZATION_LEVEL = s; MACOSX_DEPLOYMENT_TARGET = 10.10; OTHER_SWIFT_FLAGS = "-DXcode"; PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = macosx; SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; USE_HEADERMAP = NO; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ E8D4CF402109F07D008476B8 /* Build configuration list for PBXNativeTarget "EtherWalletKitTest" */ = { isa = XCConfigurationList; buildConfigurations = ( E8D4CF412109F07D008476B8 /* Debug */, E8D4CF422109F07D008476B8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; OBJ_18 /* Build configuration list for PBXNativeTarget "EtherWalletKit" */ = { isa = XCConfigurationList; buildConfigurations = ( OBJ_19 /* Debug */, OBJ_20 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; OBJ_2 /* Build configuration list for PBXProject "EtherWalletKit" */ = { isa = XCConfigurationList; buildConfigurations = ( OBJ_3 /* Debug */, OBJ_4 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; OBJ_25 /* Build configuration list for PBXNativeTarget "EtherWalletKitPackageDescription" */ = { isa = XCConfigurationList; buildConfigurations = ( OBJ_26 /* Debug */, OBJ_27 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; OBJ_31 /* Build configuration list for PBXAggregateTarget "EtherWalletKitPackageTests" */ = { isa = XCConfigurationList; buildConfigurations = ( OBJ_32 /* Debug */, OBJ_33 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; OBJ_36 /* Build configuration list for PBXNativeTarget "EtherWalletKitTests" */ = { isa = XCConfigurationList; buildConfigurations = ( OBJ_37 /* Debug */, OBJ_38 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = OBJ_1 /* Project object */; } ================================================ FILE: EtherWalletKit.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: EtherWalletKit.xcodeproj/xcshareddata/xcschemes/EtherWalletKit-Package.xcscheme ================================================ ================================================ FILE: EtherWalletKit.xcodeproj/xcshareddata/xcschemes/xcschememanagement.plist ================================================ SchemeUserState EtherWalletKit-Package.xcscheme SuppressBuildableAutocreation ================================================ FILE: EtherWalletKit.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: EtherWalletKit.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: EtherWalletKitTest/EtherWalletKitTest.swift ================================================ import XCTest @testable import EtherWalletKit class EtherWalletKitTest: XCTestCase { private let password = "PASSWORD123" func testAccount() { guard let _ = try? EtherWallet.account.generateAccount(password: password) else { XCTFail() return } XCTAssert(EtherWallet.account.hasAccount) guard let address = EtherWallet.account.address else { XCTFail() return } XCTAssert(address.count == 42) guard let privateKey = try? EtherWallet.account.privateKey(password: password) else { XCTFail() return } XCTAssert(privateKey.count == 64) guard let _ = try? EtherWallet.account.importAccount(privateKey: privateKey, password: password) else { XCTFail() return } XCTAssert(address == EtherWallet.account.address) XCTAssert(EtherWallet.account.verifyPassword(password)) XCTAssertFalse(EtherWallet.account.verifyPassword("WRONG_PASSWORD")) } func testBalance() { XCTAssert(try! EtherWallet.balance.etherBalanceSync() == "0") XCTAssert(try! EtherWallet.balance.tokenBalanceSync(contractAddress: "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07") == "0") } } ================================================ FILE: EtherWalletKitTest/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString 1.0 CFBundleVersion 1 ================================================ FILE: LICENSE ================================================ Copyright (c) 2018 SteadyAction Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Package.swift ================================================ // swift-tools-version:4.0 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "EtherWalletKit", products: [ // Products define the executables and libraries produced by a package, and make them visible to other packages. .library( name: "EtherWalletKit", targets: ["EtherWalletKit"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target( name: "EtherWalletKit", dependencies: []), .testTarget( name: "EtherWalletKitTests", dependencies: ["EtherWalletKit"]), ] ) ================================================ FILE: Podfile ================================================ use_frameworks! target 'EtherWalletKit' do platform :ios, '10.0' pod "web3swift", '~> 2.0' pod 'SwiftKeychainWrapper' end target 'EtherWalletKitTest' do pod "web3swift", '~> 2.0' end ================================================ FILE: README.md ================================================

EtherWalletKit [![Swift](https://img.shields.io/badge/Swift-4.2-orange.svg)](https://swift.org) [![Xcode](https://img.shields.io/badge/Xcode-10.0-blue.svg)](https://developer.apple.com/xcode) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) iOS ## Introduction EtherWalletKit is an Ethereum Wallet Toolkit for iOS.

I hope cryptocurrency and decentralized token economy become more widely adapted. However, some developers hesitate to add a crypto wallet on apps since blockchain and cryptocurrency are complex and require many new knowledge.

Don't worry.
With EtherWalletKit, you can implement an Ethereum wallet without a server and blockchain knowledge. ## Features #### Released Features * Creating/Importing an account(address and private key) * Checking Ether and tokens balance * Sending Ether and tokens to other addresses * Browsing token information * Testnet(Rinkeby & Ropsten) support * BIP39 Mnemonics #### Planned Features * Browsing transaction history * Keystore import / export * Custom configuration / advanced transactions * Multiple accounts * Third party APIs * ERC-721 supports ## Installation ### CocoaPods

To integrate EtherWalletKit into your Xcode project using CocoaPods, specify it in your Podfile:

pod 'EtherWalletKit'
## Quick Start #### 0. Don't forget to import it ``` swift import EtherWalletKit ``` #### 1. Create an Ethereum Wallet ```swift // Generate a new account with its new password. try? EtherWallet.account.generateAccount(password: "ABCDEFG") // Import an existing account from its private key and set its new password. try? EtherWallet.account.importAccount(privateKey: "1dcbc1d6e0a4587a3a9095984cf051a1bc6ed975f15380a0ac97f01c0c045062, password: "ABCDEFG") ``` Note: ```password``` will be encrypted and saved to the device and it will be required to access the wallet. #### 2. Get balance ```swift // Get balance of Ether EtherWallet.balance.etherBalance { balance in print(balance) } // Get balance of a token EtherWallet.balance.tokenBalance(contractAddress: "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07") { balance in print(balance) } ``` #### 3. Send ```swift // send Ether to an address. EtherWallet.transaction.sendEther(to: "0x7777787C97a35d37Db8E5afb0C92BCfd4F6480bE", amount: "1.5", password: "ABCDEFG") { txHash in print(txHash) } // send a token to an address. EtherWallet.transaction.sendToken(to: "0x7777787C97a35d37Db8E5afb0C92BCfd4F6480bE", contractAddress: "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07", amount: "20", password: "ABCDEFG", decimal: 18) { txHash in print(txHash) } ``` Note: ```password``` should be eqaul to the password of wallet created. Also you can put ```gasPrice``` as an extra parameter to set gas price for the transcation. For full documentation, please see [THIS](./Docs/Document.md). ## Notes * Nothing will be sent to a server. Everything will be worked on the local device and Ethereum Blockchain. * You dont need to download and sync the nodes because [Infura](https://infura.io/) is doing it for you. * ```password``` for wallet is equal to the password for the keystore file. Always make sure a ```password``` is long enough for security. ## Contribution * Make sure you have a [GitHub account](https://github.com/signup/free) * Create a GitHub pull request for your contribution * Clearly describe the issue or feature. * Fork the repository on GitHub * Create a topic branch from where you want to base your work. ([Gitflow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) is welcome) * Please avoid working directly on the `master` branch. * Make sure you have added the necessary tests for your changes and make sure all tests pass. ## License EtherWalletKit is available under the MIT license. See the [LICENSE](./LICENSE) file for more info. ================================================ FILE: Sources/Structure/EtherscanAPIResponse.swift ================================================ struct EtherscanTxAPIResponse: Decodable { let message: String let status: String let result: [GeneralTransactionData] } struct EtherscanTokenTxAPIResponse: Decodable { let message: String let status: String let result: [TokenTransactionData] } ================================================ FILE: Sources/Structure/EthplorerAPIResponse.swift ================================================ struct EthplorerTokenInfoAPIResponse: Decodable { let address: String let name: String let symbol: String let decimals: String let totalSupply: String } ================================================ FILE: Sources/Structure/GasStationAPIResponse.swift ================================================ struct GasStationAPIResponse: Decodable { let safeLow: Double let average: Double let fastest: Double } ================================================ FILE: Sources/Structure/TransactionData.swift ================================================ struct TransactionData { let currencyName: String let currencySymbol: String let amount: String let timestamp: String let hash: String let from: String let to: String let isError: Bool } struct TokenTransactionData: Decodable { let tokenName: String let tokenSymbol: String let tokenDecimal: String let timestamp: String let hash: String let from: String let to: String var value: String let gas: String let gasPrice: String let contractAddress: String let cumulativeGasUsed: String let gasUsed: String let confirmations: String enum CodingKeys: String, CodingKey { case tokenName case tokenSymbol case tokenDecimal case timestamp = "timeStamp" case hash case from case to case value case gas case gasPrice case contractAddress case cumulativeGasUsed case gasUsed case confirmations } } struct GeneralTransactionData: Decodable { let timestamp: String let hash: String let from: String let to: String var value: String let gas: String let gasPrice: String let isError: String let contractAddress: String let cumulativeGasUsed: String let gasUsed: String let confirmations: String enum CodingKeys: String, CodingKey { case timestamp = "timeStamp" case hash case from case to case value case gas case gasPrice case isError case contractAddress case cumulativeGasUsed case gasUsed case confirmations } } ================================================ FILE: Sources/Wallet/EtherWallet+Account.swift ================================================ import Web3swift import EthereumAddress import SwiftKeychainWrapper public protocol AccountService { var hasAccount: Bool { get } var address: String? { get } var mnemonics: String? { get set } func privateKey(password: String) throws -> String func verifyPassword(_ password: String) -> Bool func generateAccount(password: String) throws func importAccount(privateKey: String, password: String) throws func importAccount(mnemonics: String, password: String) throws } extension EtherWallet: AccountService { public var hasAccount: Bool { return (try? loadKeystore()) != nil } public var address: String? { guard let keystore = try? loadKeystore() else { return nil } return keystore.getAddress()?.address } public var mnemonics: String? { get { return KeychainWrapper.standard.string(forKey: mnemonicsKeystoreKey) } set { if let newValue = newValue { KeychainWrapper.standard.set(newValue, forKey: mnemonicsKeystoreKey) } else { KeychainWrapper.standard.removeObject(forKey: mnemonicsKeystoreKey) } } } public func privateKey(password: String) throws -> String { let keystore = try loadKeystore() guard let address = keystore.getAddress()?.address else { throw WalletError.malformedKeystore } guard let ethereumAddress = EthereumAddress(address) else { throw WalletError.invalidAddress } let privateKeyData = try keystore.UNSAFE_getPrivateKeyData(password: password, account: ethereumAddress) return privateKeyData.toHexString() } public func verifyPassword(_ password: String) -> Bool { return (try? privateKey(password: password)) != nil } public func generateAccount(password: String) throws { guard let mnemonics = try BIP39.generateMnemonics(bitsOfEntropy: 128) else { throw WalletError.unexpectedResult } try importAccount(mnemonics: mnemonics, password: password) } public func importAccount(privateKey: String, password: String) throws { guard let privateKeyData = Data.fromHex(privateKey) else { throw WalletError.invalidKey } guard let keystore = try EthereumKeystoreV3(privateKey: privateKeyData, password: password) else { throw WalletError.malformedKeystore } try saveKeystore(keystore) self.mnemonics = nil } public func importAccount(mnemonics: String, password: String) throws { guard let keystore = (try? BIP32Keystore(mnemonics: mnemonics, password: password)) ?? nil else { throw WalletError.invalidMnemonics } guard let address = keystore.addresses?.first else { throw WalletError.malformedKeystore } guard let privateKey = try? keystore.UNSAFE_getPrivateKeyData(password: password, account: address).toHexString() else { throw WalletError.malformedKeystore } try importAccount(privateKey: privateKey, password: password) self.mnemonics = mnemonics } private func saveKeystore(_ keystore: EthereumKeystoreV3) throws { keystoreCache = keystore guard let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else { throw WalletError.invalidPath } guard let keystoreParams = keystore.keystoreParams else { throw WalletError.malformedKeystore } guard let keystoreData = try? JSONEncoder().encode(keystoreParams) else { throw WalletError.malformedKeystore } if !FileManager.default.fileExists(atPath: userDir + keystoreDirectoryName) { do { try FileManager.default.createDirectory(atPath: userDir + keystoreDirectoryName, withIntermediateDirectories: true, attributes: nil) } catch { throw WalletError.invalidPath } } FileManager.default.createFile(atPath: userDir + keystoreDirectoryName + keystoreFileName, contents: keystoreData, attributes: nil) setupOptionsFrom() } func loadKeystore() throws -> EthereumKeystoreV3 { if let keystore = keystoreCache { return keystore } guard let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else { throw WalletError.invalidPath } guard let keystoreManager = KeystoreManager.managerForPath(userDir + keystoreDirectoryName) else { throw WalletError.malformedKeystore } guard let address = keystoreManager.addresses?.first else { throw WalletError.malformedKeystore } guard let keystore = keystoreManager.walletForAddress(address) as? EthereumKeystoreV3 else { throw WalletError.malformedKeystore } keystoreCache = keystore return keystore } } ================================================ FILE: Sources/Wallet/EtherWallet+Balance.swift ================================================ import Web3swift import EthereumAddress import BigInt public protocol BalanceService { func etherBalanceSync() throws -> String func etherBalance(completion: @escaping (String?) -> ()) func tokenBalanceSync(contractAddress: String) throws -> String func tokenBalance(contractAddress: String, completion: @escaping (String?) -> ()) } extension EtherWallet: BalanceService { public func etherBalanceSync() throws -> String { guard let address = address else { throw WalletError.accountDoesNotExist } guard let ethereumAddress = EthereumAddress(address) else { throw WalletError.invalidAddress } guard let balanceInWei = try? web3Instance.eth.getBalance(address: ethereumAddress) else { throw WalletError.networkFailure } guard let balanceInEtherUnitStr = Web3.Utils.formatToEthereumUnits(balanceInWei, toUnits: Web3.Utils.Units.eth, decimals: 8, decimalSeparator: ".") else { throw WalletError.conversionFailure } return balanceInEtherUnitStr } public func etherBalance(completion: @escaping (String?) -> ()) { DispatchQueue.global().async { let balance = try? self.etherBalanceSync() DispatchQueue.main.async { completion(balance) } } } public func tokenBalanceSync(contractAddress: String) throws -> String { let contractEthreumAddress = EthereumAddress(contractAddress) guard let contract = web3Instance.contract(Web3.Utils.erc20ABI, at: contractEthreumAddress) else { throw WalletError.invalidAddress } guard let address = address else { throw WalletError.accountDoesNotExist } let parameters = [address as AnyObject] let contractMethod = contract.method("balanceOf", parameters: parameters, extraData: Data(), transactionOptions: transactionOptions) guard let balanceInfo = try? contractMethod?.call(transactionOptions: nil), let balance = balanceInfo?["0"] as? BigUInt else { throw WalletError.networkFailure } return "\(balance)" } public func tokenBalance(contractAddress: String, completion: @escaping (String?) -> ()) { DispatchQueue.global().async { let balance = try? self.tokenBalanceSync(contractAddress: contractAddress) DispatchQueue.main.async { completion(balance) } } } } ================================================ FILE: Sources/Wallet/EtherWallet+History.swift ================================================ import Web3swift public protocol HistoryService { } extension EtherWallet: HistoryService { } ================================================ FILE: Sources/Wallet/EtherWallet+Info.swift ================================================ import Web3swift import EthereumAddress public protocol InfoService { func decimalsForTokenSync(address: String) throws -> Int func decimalsForToken(address: String, completion: @escaping (Int?) -> ()) func symbolForTokenSync(address: String) throws -> String func symbolForToken(address: String, completion: @escaping (String?) -> ()) } extension EtherWallet: InfoService { public func decimalsForTokenSync(address: String) throws -> Int { let contract = try erc20contract(address: address) let parameters = [AnyObject]() guard let decimalsInfo = try? contract.method("decimals", parameters: parameters, extraData: Data(), transactionOptions: transactionOptions)?.call(transactionOptions: nil), let decimals = decimalsInfo?["0"] else { throw WalletError.networkFailure } guard let result = decimals as? Int else { throw WalletError.unexpectedResult } return result } public func decimalsForToken(address: String, completion: @escaping (Int?) -> ()) { DispatchQueue.global().async { let decimals = try? self.decimalsForTokenSync(address: address) DispatchQueue.main.async { completion(decimals) } } } public func symbolForTokenSync(address: String) throws -> String { let contract = try erc20contract(address: address) let parameters = [AnyObject]() guard let symbolInfo = try? contract.method("symbol", parameters: parameters, extraData: Data(), transactionOptions: transactionOptions)?.call(transactionOptions: nil), let symbol = symbolInfo?["0"] as? String else { throw WalletError.networkFailure } if symbol.rangeOfCharacter(from: CharacterSet.alphanumerics.inverted) != nil { throw WalletError.unexpectedResult } return symbol } public func symbolForToken(address: String, completion: @escaping (String?) -> ()) { DispatchQueue.global().async { let symbol = try? self.symbolForTokenSync(address: address) DispatchQueue.main.async { completion(symbol) } } } private func erc20contract(address: String) throws -> web3.web3contract { let contractEthreumAddress = EthereumAddress(address) guard let contract = web3Instance.contract(Web3.Utils.erc20ABI, at: contractEthreumAddress) else { throw WalletError.contractFailure } return contract } } ================================================ FILE: Sources/Wallet/EtherWallet+Transaction.swift ================================================ import Web3swift import EthereumAddress import BigInt public protocol TransactionService { func sendEtherSync(to address: String, amount: String, password: String) throws -> String func sendEtherSync(to address: String, amount: String, password: String, gasPrice: String?) throws -> String func sendEther(to address: String, amount: String, password: String, completion: @escaping (String?) -> ()) func sendEther(to address: String, amount: String, password: String, gasPrice: String?, completion: @escaping (String?) -> ()) func sendTokenSync(to toAddress: String, contractAddress: String, amount: String, password: String, decimal: Int) throws -> String func sendTokenSync(to toAddress: String, contractAddress: String, amount: String, password: String, decimal: Int, gasPrice: String?) throws -> String func sendToken(to toAddress: String, contractAddress: String, amount: String, password: String, decimal:Int, completion: @escaping (String?) -> ()) func sendToken(to toAddress: String, contractAddress: String, amount: String, password: String, decimal:Int, gasPrice: String?, completion: @escaping (String?) -> ()) } extension EtherWallet: TransactionService { public func sendEtherSync(to address: String, amount: String, password: String) throws -> String { return try sendEtherSync(to: address, amount: amount, password: password, gasPrice: nil) } public func sendEtherSync(to address: String, amount: String, password: String, gasPrice: String?) throws -> String { guard let toAddress = EthereumAddress(address) else { throw WalletError.invalidAddress } let keystore = try loadKeystore() let etherBalance = try etherBalanceSync() guard let etherBalanceInDouble = Double(etherBalance) else { throw WalletError.conversionFailure } guard let amountInDouble = Double(amount) else { throw WalletError.conversionFailure } guard etherBalanceInDouble >= amountInDouble else { throw WalletError.notEnoughBalance } let keystoreManager = KeystoreManager([keystore]) web3Instance.addKeystoreManager(keystoreManager) if let gasPrice = gasPrice { options.gasPrice = BigUInt(gasPrice) } options.value = Web3.Utils.parseToBigUInt(amount, units: .eth) guard let contract = web3Instance.contract(Web3.Utils.coldWalletABI, at: toAddress, abiVersion: 2) else { throw WalletError.contractFailure } contract.transactionOptions = transactionOptions guard let intermediateSend = contract.method() else { throw WalletError.contractFailure } guard let sendResult = try? intermediateSend.send(password: password) else { throw WalletError.networkFailure } return sendResult.hash } public func sendEther(to address: String, amount: String, password: String, completion: @escaping (String?) -> ()) { sendEther(to: address, amount: amount, password: password, gasPrice: nil, completion: completion) } public func sendEther(to address: String, amount: String, password: String, gasPrice: String?, completion: @escaping (String?) -> ()) { DispatchQueue.global().async { let txHash = try? self.sendEtherSync(to: address, amount: amount, password: password, gasPrice: gasPrice) DispatchQueue.main.async { completion(txHash) } } } public func sendTokenSync(to toAddress: String, contractAddress: String, amount: String, password: String, decimal: Int) throws -> String { return try sendTokenSync(to: toAddress, contractAddress: contractAddress, amount: amount, password: password, decimal: decimal, gasPrice: nil) } public func sendTokenSync(to toAddress: String, contractAddress: String, amount: String, password: String, decimal: Int, gasPrice: String?) throws -> String { guard let tokenAddress = EthereumAddress(contractAddress) else { throw WalletError.invalidAddress } guard let fromAddress = address else { throw WalletError.accountDoesNotExist } guard let fromEthereumAddress = EthereumAddress(fromAddress) else { throw WalletError.invalidAddress } guard let toEthereumAddress = EthereumAddress(toAddress) else { throw WalletError.invalidAddress } let keystore = try loadKeystore() let keystoreManager = KeystoreManager([keystore]) web3Instance.addKeystoreManager(keystoreManager) var options = Web3Options.defaultOptions() options.from = fromEthereumAddress if let gasPrice = gasPrice { options.gasPrice = BigUInt(gasPrice) } options.gasLimit = BigUInt(defaultGasLimitForTokenTransfer) guard let tokenAmount = Web3.Utils.parseToBigUInt(amount, decimals: decimal) else { throw WalletError.conversionFailure } let parameters = [toEthereumAddress, tokenAmount] as [AnyObject] guard let contract = web3Instance.contract(Web3.Utils.erc20ABI, at: tokenAddress, abiVersion: 2) else { throw WalletError.contractFailure } guard let contractMethod = contract.method("transfer", parameters: parameters, extraData: Data(), transactionOptions: transactionOptions) else { throw WalletError.contractFailure } var newTransactionOptions = transactionOptions newTransactionOptions.callOnBlock = .latest guard let contractCall = try? contractMethod.send(password: password, transactionOptions: newTransactionOptions) else { throw WalletError.networkFailure } return contractCall.hash } public func sendToken(to toAddress: String, contractAddress: String, amount: String, password: String, decimal: Int, completion: @escaping (String?) -> ()) { sendToken(to: toAddress, contractAddress: contractAddress, amount: amount, password: password, decimal: decimal, gasPrice: nil, completion: completion) } public func sendToken(to toAddress: String, contractAddress: String, amount: String, password: String, decimal:Int, gasPrice: String?, completion: @escaping (String?) -> ()) { DispatchQueue.global().async { let txHash = try? self.sendTokenSync(to: toAddress, contractAddress: contractAddress, amount: amount, password: password, decimal: decimal, gasPrice: gasPrice) DispatchQueue.main.async { completion(txHash) } } } } ================================================ FILE: Sources/Wallet/EtherWallet+Util.swift ================================================ import Web3swift public protocol UtilService { } extension EtherWallet: UtilService { } ================================================ FILE: Sources/Wallet/EtherWallet.swift ================================================ import Web3swift import EthereumAddress import BigInt public class EtherWallet { private static let shared = EtherWallet() public static let account: AccountService = EtherWallet.shared public static let balance: BalanceService = EtherWallet.shared public static let info: InfoService = EtherWallet.shared public static let transaction: TransactionService = EtherWallet.shared public static let util: UtilService = EtherWallet.shared private let web3Main = Web3.InfuraMainnetWeb3() let keystoreDirectoryName = "/keystore" let keystoreFileName = "/key.json" let mnemonicsKeystoreKey = "mnemonicsKeystoreKey" let defaultGasLimitForTokenTransfer = 100000 var options: Web3Options var transactionOptions: TransactionOptions var keystoreCache: EthereumKeystoreV3? var web3Instance: web3 { return web3Main } private init() { options = Web3Options.defaultOptions() options.gasLimit = BigUInt(defaultGasLimitForTokenTransfer) transactionOptions = TransactionOptions.defaultOptions transactionOptions.gasLimit = .limited(BigUInt(defaultGasLimitForTokenTransfer)) setupOptionsFrom() } func setupOptionsFrom() { if let address = address { options.from = EthereumAddress(address) transactionOptions.from = EthereumAddress(address) } else { options.from = nil transactionOptions.from = nil } } } ================================================ FILE: Sources/Wallet/EtherWalletTestnets.swift ================================================ import Web3swift public class EtherWalletRinkeby: EtherWallet { private let web3Rinkeby = Web3.InfuraRinkebyWeb3() override var web3Instance: web3 { return web3Rinkeby } } public class EtherWalletRopsten: EtherWallet { private let web3Ropsten = Web3.InfuraRopstenWeb3() override var web3Instance: web3 { return web3Ropsten } } ================================================ FILE: Sources/Wallet/WalletError.swift ================================================ public enum WalletError: Error { case accountDoesNotExist case invalidPath case invalidKey case invalidMnemonics case invalidAddress case malformedKeystore case networkFailure case conversionFailure case notEnoughBalance case contractFailure case unexpectedResult }