Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions EthereumKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 9T7JPNQ2UD;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
Expand All @@ -792,7 +792,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 9T7JPNQ2UD;
DEVELOPMENT_TEAM = "";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/iOS",
Expand Down
35 changes: 21 additions & 14 deletions EthereumKit/Helper/Network.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ public enum Network {
case mainnet
case ropsten
case kovan
case rinkeby
case `private`(chainID: Int, testUse: Bool)

public init?(name: String, chainID: Int = 0, testUse: Bool = false) {
switch name {
case "main":
Expand All @@ -12,56 +13,58 @@ public enum Network {
self = .ropsten
case "kovan":
self = .kovan
case "rinkeby":
self = .rinkeby
case "private":
self = .private(chainID: chainID, testUse: testUse)
default:
return nil
}
}

// https://github.com/satoshilabs/slips/blob/master/slip-0044.md
public var coinType: UInt32 {
let mainnetCoinType = UInt32(60)
let testnetCoinType = UInt32(1)

switch self {
case .mainnet:
return mainnetCoinType
case .ropsten, .kovan:
case .ropsten, .kovan, .rinkeby:
return testnetCoinType
case .private(_, let testUse):
return testUse ? testnetCoinType : mainnetCoinType
}
}

public var privateKeyPrefix: UInt32 {
let mainnetPrefix: UInt32 = 0x0488ade4
let testnetPrefix: UInt32 = 0x04358394

switch self {
case .mainnet:
return mainnetPrefix
case .ropsten, .kovan:
case .ropsten, .kovan, .rinkeby:
return testnetPrefix
case .private(_, let testUse):
return testUse ? testnetPrefix : mainnetPrefix
}
}

public var publicKeyPrefix: UInt32 {
let mainnetPrefix: UInt32 = 0x0488b21e
let testnetPrefix: UInt32 = 0x043587cf

switch self {
case .mainnet:
return mainnetPrefix
case .ropsten, .kovan:
case .ropsten, .kovan, .rinkeby:
return testnetPrefix
case .private(_, let testUse):
return testUse ? testnetPrefix : mainnetPrefix
}
}

public var name: String {
switch self {
case .mainnet:
Expand All @@ -70,11 +73,13 @@ public enum Network {
return "Ropsten"
case .kovan:
return "Kovan"
case .private(_, _):
case .rinkeby:
return "Rinkeby"
case .private:
return "Privatenet"
}
}

public var chainID: Int {
switch self {
case .mainnet:
Expand All @@ -83,6 +88,8 @@ public enum Network {
return 3
case .kovan:
return 42
case .rinkeby:
return 4
case .private(let chainID, _):
return chainID
}
Expand All @@ -92,7 +99,7 @@ public enum Network {
extension Network: Equatable {
public static func == (lhs: Network, rhs: Network) -> Bool {
switch (lhs, rhs) {
case (.mainnet, .mainnet), (.ropsten, .ropsten), (.kovan, .kovan):
case (.mainnet, .mainnet), (.ropsten, .ropsten), (.kovan, .kovan), (.rinkeby, .rinkeby):
return true
case (.private(let firstChainID, let firstTestUse), .private(let secondChainID, let secondTestUse)):
return firstChainID == secondChainID && firstTestUse == secondTestUse
Expand Down
14 changes: 7 additions & 7 deletions EthereumKit/Mnemonic/Mnemonic.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,35 @@ import Foundation
public final class Mnemonic {
public enum Strength: Int {
case normal = 128
case hight = 256
case high = 256
}

public static func create(strength: Strength = .normal, language: WordList = .english) -> [String] {
let byteCount = strength.rawValue / 8
var bytes = Data(count: byteCount)
_ = bytes.withUnsafeMutableBytes { SecRandomCopyBytes(kSecRandomDefault, byteCount, $0) }
return create(entropy: bytes, language: language)
}

public static func create(entropy: Data, language: WordList = .english) -> [String] {
let entropybits = String(entropy.flatMap { ("00000000" + String($0, radix: 2)).suffix(8) })
let hashBits = String(entropy.sha256().flatMap { ("00000000" + String($0, radix: 2)).suffix(8) })
let checkSum = String(hashBits.prefix((entropy.count * 8) / 32))

let words = language.words
let concatenatedBits = entropybits + checkSum

var mnemonic: [String] = []
for index in 0..<(concatenatedBits.count / 11) {
let startIndex = concatenatedBits.index(concatenatedBits.startIndex, offsetBy: index * 11)
let endIndex = concatenatedBits.index(startIndex, offsetBy: 11)
let wordIndex = Int(strtoul(String(concatenatedBits[startIndex..<endIndex]), nil, 2))
mnemonic.append(String(words[wordIndex]))
}

return mnemonic
}

public static func createSeed(mnemonic: [String], withPassphrase passphrase: String = "") throws -> Data {
let words = WordList.english.words + WordList.japanese.words
guard !mnemonic.map({ words.contains($0) }).contains(false) else {
Expand Down
21 changes: 12 additions & 9 deletions EthereumKit/Networking/HTTPClient/Configuration.swift
Original file line number Diff line number Diff line change
@@ -1,37 +1,40 @@
/// Configuration has necessary information to use in Geth network
public struct Configuration {

/// represents which network to use
public let network: Network

/// represents an endpoint of ethereum node to connect to
public let nodeEndpoint: String

/// represents an etherscan api key
public let etherscanAPIKey: String

/// represents whether to print debug logs in console
public let debugPrints: Bool

public init(network: Network, nodeEndpoint: String, etherscanAPIKey: String, debugPrints: Bool) {
self.network = network
self.nodeEndpoint = nodeEndpoint
self.etherscanAPIKey = etherscanAPIKey
self.debugPrints = debugPrints
}

/// reprensets an etherscan url based on which network to use
public var etherscanURL: URL {
switch network {
case .mainnet:
return URL(string: "https://api.etherscan.io")!

case .ropsten:
return URL(string: "https://ropsten.etherscan.io")!

case .kovan:
return URL(string: "https://kovan.etherscan.io")!


case .rinkeby:
return URL(string: "https://rinkeby.etherscan.io/")!

case .private:
// NOTE: does not get any transactions because of private network.
return URL(string: "https://ropsten.etherscan.io")!
Expand Down
30 changes: 21 additions & 9 deletions EthereumKitTests/NetworkTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,60 +2,72 @@ import XCTest
@testable import EthereumKit

final class NetworkTests: XCTestCase {

func testMainnet() {
let network = Network.mainnet
XCTAssert(network.chainID == 1)
XCTAssert(network.coinType == 60)
XCTAssert(network.privateKeyPrefix == 0x0488ade4)
XCTAssert(network.publicKeyPrefix == 0x0488b21e)
}

func testRopsten() {
let network = Network.ropsten
XCTAssert(network.chainID == 3)
XCTAssert(network.coinType == 1)
XCTAssert(network.privateKeyPrefix == 0x04358394)
XCTAssert(network.publicKeyPrefix == 0x043587cf)
}

func testKovan() {
let network = Network.kovan
XCTAssert(network.chainID == 42)
XCTAssert(network.coinType == 1)
XCTAssert(network.privateKeyPrefix == 0x04358394)
XCTAssert(network.publicKeyPrefix == 0x043587cf)
}


func testRinkeby() {
let network = Network.rinkeby
XCTAssert(network.chainID == 4)
XCTAssert(network.coinType == 1)
XCTAssert(network.privateKeyPrefix == 0x04358394)
XCTAssert(network.publicKeyPrefix == 0x043587cf)
}

func testPrivateNetTestUse() {
let network = Network.private(chainID: 100, testUse: true)
XCTAssert(network.chainID == 100)
XCTAssert(network.coinType == 1)
XCTAssert(network.privateKeyPrefix == 0x04358394)
XCTAssert(network.publicKeyPrefix == 0x043587cf)
}

func testPrivateNet() {
let network = Network.private(chainID: 100, testUse: false)
XCTAssert(network.chainID == 100)
XCTAssert(network.coinType == 60)
XCTAssert(network.privateKeyPrefix == 0x0488ade4)
XCTAssert(network.publicKeyPrefix == 0x0488b21e)
}

func testNetworkInitializer() {
let mainNetwork = Network(name: "main")
XCTAssertNotNil(mainNetwork)
XCTAssertEqual(mainNetwork, Network.mainnet)

let ropstenNetwork = Network(name: "ropsten")
XCTAssertNotNil(ropstenNetwork)
XCTAssertEqual(ropstenNetwork, Network.ropsten)

let kovanNetwork = Network(name: "kovan")
XCTAssertNotNil(kovanNetwork)
XCTAssertEqual(kovanNetwork, Network.kovan)


let rinkebyNetwork = Network(name: "rinkeby")
XCTAssertNotNil(rinkebyNetwork)
XCTAssertEqual(rinkebyNetwork, Network.rinkeby)

let privateNetwork = Network(name: "private", chainID: 1, testUse: false)
XCTAssertNotNil(privateNetwork)
XCTAssertEqual(privateNetwork, Network.private(chainID: 1, testUse: false))
Expand Down