├── .gitignore ├── AddressGenerator.xcodeproj ├── project.pbxproj └── xcshareddata │ └── xcschemes │ └── AddressGenerator.xcscheme ├── AddressGenerator ├── AddressGenerator.entitlements ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── icon_128@1x.png │ │ ├── icon_128@2x.png │ │ ├── icon_16@1x.png │ │ ├── icon_16@2x.png │ │ ├── icon_256@1x.png │ │ ├── icon_256@2x.png │ │ ├── icon_32@1x.png │ │ ├── icon_32@2x.png │ │ ├── icon_512@1x.png │ │ └── icon_512@2x.png │ ├── Coins │ │ ├── Bitcoin.imageset │ │ │ ├── Bitcoin.png │ │ │ └── Contents.json │ │ ├── Contents.json │ │ ├── Dash.imageset │ │ │ ├── Contents.json │ │ │ └── Dash.png │ │ ├── Ethereum.imageset │ │ │ ├── Contents.json │ │ │ └── Ethereum.png │ │ ├── Litecoin.imageset │ │ │ ├── Contents.json │ │ │ └── Litecoin.png │ │ ├── Others.imageset │ │ │ ├── Contents.json │ │ │ └── Others.png │ │ └── Ripple.imageset │ │ │ ├── Contents.json │ │ │ └── ripple.png │ └── Contents.json ├── Base.lproj │ └── Main.storyboard ├── Controllers │ ├── AccountController.swift │ ├── BaseController.swift │ ├── CoinsController.swift │ ├── MainController.swift │ └── WindowController.swift ├── Info.plist ├── Library │ ├── AddressGenerator-Bridging-Header.h │ ├── Crypto │ │ ├── Coin │ │ │ ├── Account.swift │ │ │ ├── Bitcoin.swift │ │ │ ├── CoinAware.swift │ │ │ ├── Ethereum.swift │ │ │ ├── Monero.swift │ │ │ └── Ripple.swift │ │ ├── Engine │ │ │ ├── CoinList.swift │ │ │ ├── EthereumGenerator.swift │ │ │ ├── InternalError.swift │ │ │ ├── KeyPairGenerator.swift │ │ │ ├── Manager.swift │ │ │ ├── MoneroGenerator.swift │ │ │ ├── Pay2PubKeyHashGenerator.swift │ │ │ ├── Pay2ScriptHashGenerator.swift │ │ │ ├── PublicKeyCompressor.swift │ │ │ ├── RippleGenerator.swift │ │ │ ├── SwiftBaseX.swift │ │ │ ├── Task.swift │ │ │ └── WalletImportFormatGenerator.swift │ │ ├── Extensions │ │ │ ├── Data+Extensions.swift │ │ │ ├── String+Extensions.swift │ │ │ └── UnsafePointer+Extensions.swift │ │ └── Hash │ │ │ └── keccak │ │ │ ├── KeccakHash.swift │ │ │ ├── sha3.c │ │ │ └── sha3.h │ └── Utils │ │ └── QRCodeGenerator.swift └── Views │ ├── Cell.swift │ └── Label.swift ├── AddressGeneratorTests ├── AddressGeneratorTests.swift ├── CoinListTests.swift ├── DataExtensionsTests.swift ├── EthereumGeneratorTests.swift ├── Info.plist ├── KeccakHashTests.swift ├── KeyPairGeneratorTests.swift ├── PublicKeyCompressorTests.swift ├── RippleGeneratorTests.swift └── WalletImportGeneratorTests.swift ├── LICENSE.md ├── Podfile ├── Podfile.lock ├── README.md └── Screenshots ├── Artboard.png ├── demo.png ├── s1.png ├── s2.png └── s3.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | *.xcworkspace 20 | !default.xcworkspace 21 | 22 | #CocoaPods 23 | Pods 24 | -------------------------------------------------------------------------------- /AddressGenerator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 61689E2C7EEC96F5AAB50DB2 /* Pods_AddressGenerator.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7753C92C713B97532BDE1954 /* Pods_AddressGenerator.framework */; }; 11 | D218AAA82001378A004A252D /* RippleGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAA72001378A004A252D /* RippleGeneratorTests.swift */; }; 12 | D218AAAA20013822004A252D /* PublicKeyCompressorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAA920013822004A252D /* PublicKeyCompressorTests.swift */; }; 13 | D218AACA20013D56004A252D /* KeccakHash.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAAE20013D56004A252D /* KeccakHash.swift */; }; 14 | D218AACB20013D56004A252D /* sha3.c in Sources */ = {isa = PBXBuildFile; fileRef = D218AAB120013D56004A252D /* sha3.c */; }; 15 | D218AACC20013D56004A252D /* String+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAB320013D56004A252D /* String+Extensions.swift */; }; 16 | D218AACD20013D56004A252D /* UnsafePointer+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAB420013D56004A252D /* UnsafePointer+Extensions.swift */; }; 17 | D218AACE20013D56004A252D /* Data+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAB520013D56004A252D /* Data+Extensions.swift */; }; 18 | D218AACF20013D56004A252D /* Bitcoin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAB720013D56004A252D /* Bitcoin.swift */; }; 19 | D218AAD020013D56004A252D /* Ripple.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAB820013D56004A252D /* Ripple.swift */; }; 20 | D218AAD120013D56004A252D /* Ethereum.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAB920013D56004A252D /* Ethereum.swift */; }; 21 | D218AAD220013D56004A252D /* CoinAware.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AABA20013D56004A252D /* CoinAware.swift */; }; 22 | D218AAD320013D56004A252D /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AABB20013D56004A252D /* Account.swift */; }; 23 | D218AAD420013D56004A252D /* CoinList.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AABD20013D56004A252D /* CoinList.swift */; }; 24 | D218AAD520013D56004A252D /* KeyPairGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AABE20013D56004A252D /* KeyPairGenerator.swift */; }; 25 | D218AAD620013D56004A252D /* Manager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AABF20013D56004A252D /* Manager.swift */; }; 26 | D218AAD720013D56004A252D /* SwiftBaseX.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC020013D56004A252D /* SwiftBaseX.swift */; }; 27 | D218AAD820013D56004A252D /* Pay2ScriptHashGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC120013D56004A252D /* Pay2ScriptHashGenerator.swift */; }; 28 | D218AAD920013D56004A252D /* InternalError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC220013D56004A252D /* InternalError.swift */; }; 29 | D218AADA20013D56004A252D /* EthereumGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC320013D56004A252D /* EthereumGenerator.swift */; }; 30 | D218AADB20013D56004A252D /* WalletImportFormatGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC420013D56004A252D /* WalletImportFormatGenerator.swift */; }; 31 | D218AADC20013D56004A252D /* PublicKeyCompressor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC520013D56004A252D /* PublicKeyCompressor.swift */; }; 32 | D218AADD20013D56004A252D /* RippleGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC620013D56004A252D /* RippleGenerator.swift */; }; 33 | D218AADE20013D56004A252D /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC720013D56004A252D /* Task.swift */; }; 34 | D218AADF20013D56004A252D /* Pay2PubKeyHashGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAC820013D56004A252D /* Pay2PubKeyHashGenerator.swift */; }; 35 | D218AAE220013DB8004A252D /* QRCodeGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218AAE120013DB8004A252D /* QRCodeGenerator.swift */; }; 36 | D218E9131FE2C37800438A19 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218E9121FE2C37800438A19 /* AppDelegate.swift */; }; 37 | D218E9171FE2C37800438A19 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D218E9161FE2C37800438A19 /* Assets.xcassets */; }; 38 | D218E91A1FE2C37800438A19 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D218E9181FE2C37800438A19 /* Main.storyboard */; }; 39 | D218E9261FE2C37800438A19 /* AddressGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D218E9251FE2C37800438A19 /* AddressGeneratorTests.swift */; }; 40 | D24EF2912002D770002ECD08 /* MoneroGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24EF2902002D770002ECD08 /* MoneroGenerator.swift */; }; 41 | D24EF2932002D78E002ECD08 /* Monero.swift in Sources */ = {isa = PBXBuildFile; fileRef = D24EF2922002D78E002ECD08 /* Monero.swift */; }; 42 | D25570971FEBCDBD00AA443F /* CoinsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D25570961FEBCDBD00AA443F /* CoinsController.swift */; }; 43 | D255709A1FEBCDE600AA443F /* AccountController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D25570991FEBCDE600AA443F /* AccountController.swift */; }; 44 | D255709C1FEBD07400AA443F /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = D255709B1FEBD07400AA443F /* Label.swift */; }; 45 | D255709E1FEBD2B200AA443F /* MainController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D255709D1FEBD2B100AA443F /* MainController.swift */; }; 46 | D25570A01FEBD51800AA443F /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D255709F1FEBD51800AA443F /* WindowController.swift */; }; 47 | D25570A21FEBD70900AA443F /* BaseController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D25570A11FEBD70900AA443F /* BaseController.swift */; }; 48 | D25570A41FEBDCCD00AA443F /* Cell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D25570A31FEBDCCD00AA443F /* Cell.swift */; }; 49 | D2EDF5281FEACC01009BF07B /* KeccakHashTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EDF5271FEACC01009BF07B /* KeccakHashTests.swift */; }; 50 | D2EDF52A1FEACC0D009BF07B /* KeyPairGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EDF5291FEACC0D009BF07B /* KeyPairGeneratorTests.swift */; }; 51 | D2EDF52C1FEACC27009BF07B /* DataExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EDF52B1FEACC27009BF07B /* DataExtensionsTests.swift */; }; 52 | D2EDF52E1FEACC5A009BF07B /* WalletImportGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EDF52D1FEACC5A009BF07B /* WalletImportGeneratorTests.swift */; }; 53 | D2EDF5341FEAD20B009BF07B /* EthereumGeneratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EDF5331FEAD20B009BF07B /* EthereumGeneratorTests.swift */; }; 54 | D2EDF5431FEAE06C009BF07B /* CoinListTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2EDF5421FEAE06C009BF07B /* CoinListTests.swift */; }; 55 | /* End PBXBuildFile section */ 56 | 57 | /* Begin PBXContainerItemProxy section */ 58 | D218E9221FE2C37800438A19 /* PBXContainerItemProxy */ = { 59 | isa = PBXContainerItemProxy; 60 | containerPortal = D218E9071FE2C37800438A19 /* Project object */; 61 | proxyType = 1; 62 | remoteGlobalIDString = D218E90E1FE2C37800438A19; 63 | remoteInfo = AddressGenerator; 64 | }; 65 | /* End PBXContainerItemProxy section */ 66 | 67 | /* Begin PBXFileReference section */ 68 | 5063F40B8222686F291286C0 /* Pods-AddressGenerator.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AddressGenerator.debug.xcconfig"; path = "Pods/Target Support Files/Pods-AddressGenerator/Pods-AddressGenerator.debug.xcconfig"; sourceTree = ""; }; 69 | 7753C92C713B97532BDE1954 /* Pods_AddressGenerator.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AddressGenerator.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 70 | 9872C9EAB1987817A1ADC5ED /* Pods-AddressGenerator.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AddressGenerator.release.xcconfig"; path = "Pods/Target Support Files/Pods-AddressGenerator/Pods-AddressGenerator.release.xcconfig"; sourceTree = ""; }; 71 | D218AAA72001378A004A252D /* RippleGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RippleGeneratorTests.swift; sourceTree = ""; }; 72 | D218AAA920013822004A252D /* PublicKeyCompressorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicKeyCompressorTests.swift; sourceTree = ""; }; 73 | D218AAAE20013D56004A252D /* KeccakHash.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeccakHash.swift; sourceTree = ""; }; 74 | D218AAAF20013D56004A252D /* sha3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sha3.h; sourceTree = ""; }; 75 | D218AAB120013D56004A252D /* sha3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sha3.c; sourceTree = ""; }; 76 | D218AAB320013D56004A252D /* String+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+Extensions.swift"; sourceTree = ""; }; 77 | D218AAB420013D56004A252D /* UnsafePointer+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafePointer+Extensions.swift"; sourceTree = ""; }; 78 | D218AAB520013D56004A252D /* Data+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Data+Extensions.swift"; sourceTree = ""; }; 79 | D218AAB720013D56004A252D /* Bitcoin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bitcoin.swift; sourceTree = ""; }; 80 | D218AAB820013D56004A252D /* Ripple.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Ripple.swift; sourceTree = ""; }; 81 | D218AAB920013D56004A252D /* Ethereum.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Ethereum.swift; sourceTree = ""; }; 82 | D218AABA20013D56004A252D /* CoinAware.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinAware.swift; sourceTree = ""; }; 83 | D218AABB20013D56004A252D /* Account.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = ""; }; 84 | D218AABD20013D56004A252D /* CoinList.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoinList.swift; sourceTree = ""; }; 85 | D218AABE20013D56004A252D /* KeyPairGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyPairGenerator.swift; sourceTree = ""; }; 86 | D218AABF20013D56004A252D /* Manager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Manager.swift; sourceTree = ""; }; 87 | D218AAC020013D56004A252D /* SwiftBaseX.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftBaseX.swift; sourceTree = ""; }; 88 | D218AAC120013D56004A252D /* Pay2ScriptHashGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pay2ScriptHashGenerator.swift; sourceTree = ""; }; 89 | D218AAC220013D56004A252D /* InternalError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InternalError.swift; sourceTree = ""; }; 90 | D218AAC320013D56004A252D /* EthereumGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EthereumGenerator.swift; sourceTree = ""; }; 91 | D218AAC420013D56004A252D /* WalletImportFormatGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletImportFormatGenerator.swift; sourceTree = ""; }; 92 | D218AAC520013D56004A252D /* PublicKeyCompressor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PublicKeyCompressor.swift; sourceTree = ""; }; 93 | D218AAC620013D56004A252D /* RippleGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RippleGenerator.swift; sourceTree = ""; }; 94 | D218AAC720013D56004A252D /* Task.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = ""; }; 95 | D218AAC820013D56004A252D /* Pay2PubKeyHashGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pay2PubKeyHashGenerator.swift; sourceTree = ""; }; 96 | D218AAE020013D87004A252D /* AddressGenerator-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AddressGenerator-Bridging-Header.h"; sourceTree = ""; }; 97 | D218AAE120013DB8004A252D /* QRCodeGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeGenerator.swift; sourceTree = ""; }; 98 | D218E90F1FE2C37800438A19 /* AddressGenerator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AddressGenerator.app; sourceTree = BUILT_PRODUCTS_DIR; }; 99 | D218E9121FE2C37800438A19 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 100 | D218E9161FE2C37800438A19 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 101 | D218E9191FE2C37800438A19 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 102 | D218E91B1FE2C37800438A19 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 103 | D218E91C1FE2C37800438A19 /* AddressGenerator.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AddressGenerator.entitlements; sourceTree = ""; }; 104 | D218E9211FE2C37800438A19 /* AddressGeneratorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AddressGeneratorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 105 | D218E9251FE2C37800438A19 /* AddressGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressGeneratorTests.swift; sourceTree = ""; }; 106 | D218E9271FE2C37900438A19 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 107 | D24EF2902002D770002ECD08 /* MoneroGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoneroGenerator.swift; sourceTree = ""; }; 108 | D24EF2922002D78E002ECD08 /* Monero.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Monero.swift; sourceTree = ""; }; 109 | D25570961FEBCDBD00AA443F /* CoinsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinsController.swift; sourceTree = ""; }; 110 | D25570991FEBCDE600AA443F /* AccountController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountController.swift; sourceTree = ""; }; 111 | D255709B1FEBD07400AA443F /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; 112 | D255709D1FEBD2B100AA443F /* MainController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainController.swift; sourceTree = ""; }; 113 | D255709F1FEBD51800AA443F /* WindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowController.swift; sourceTree = ""; }; 114 | D25570A11FEBD70900AA443F /* BaseController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseController.swift; sourceTree = ""; }; 115 | D25570A31FEBDCCD00AA443F /* Cell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cell.swift; sourceTree = ""; }; 116 | D2EDF5271FEACC01009BF07B /* KeccakHashTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeccakHashTests.swift; sourceTree = ""; }; 117 | D2EDF5291FEACC0D009BF07B /* KeyPairGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPairGeneratorTests.swift; sourceTree = ""; }; 118 | D2EDF52B1FEACC27009BF07B /* DataExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataExtensionsTests.swift; sourceTree = ""; }; 119 | D2EDF52D1FEACC5A009BF07B /* WalletImportGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WalletImportGeneratorTests.swift; sourceTree = ""; }; 120 | D2EDF5331FEAD20B009BF07B /* EthereumGeneratorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EthereumGeneratorTests.swift; sourceTree = ""; }; 121 | D2EDF5421FEAE06C009BF07B /* CoinListTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinListTests.swift; sourceTree = ""; }; 122 | /* End PBXFileReference section */ 123 | 124 | /* Begin PBXFrameworksBuildPhase section */ 125 | D218E90C1FE2C37800438A19 /* Frameworks */ = { 126 | isa = PBXFrameworksBuildPhase; 127 | buildActionMask = 2147483647; 128 | files = ( 129 | 61689E2C7EEC96F5AAB50DB2 /* Pods_AddressGenerator.framework in Frameworks */, 130 | ); 131 | runOnlyForDeploymentPostprocessing = 0; 132 | }; 133 | D218E91E1FE2C37800438A19 /* Frameworks */ = { 134 | isa = PBXFrameworksBuildPhase; 135 | buildActionMask = 2147483647; 136 | files = ( 137 | ); 138 | runOnlyForDeploymentPostprocessing = 0; 139 | }; 140 | /* End PBXFrameworksBuildPhase section */ 141 | 142 | /* Begin PBXGroup section */ 143 | 7E6D7807200511B08B797FC8 /* Pods */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 5063F40B8222686F291286C0 /* Pods-AddressGenerator.debug.xcconfig */, 147 | 9872C9EAB1987817A1ADC5ED /* Pods-AddressGenerator.release.xcconfig */, 148 | ); 149 | name = Pods; 150 | sourceTree = ""; 151 | }; 152 | 902F97D5B227231DBE1B88C0 /* Frameworks */ = { 153 | isa = PBXGroup; 154 | children = ( 155 | 7753C92C713B97532BDE1954 /* Pods_AddressGenerator.framework */, 156 | ); 157 | name = Frameworks; 158 | sourceTree = ""; 159 | }; 160 | D218AAAB20013D56004A252D /* Crypto */ = { 161 | isa = PBXGroup; 162 | children = ( 163 | D218AAAC20013D56004A252D /* Hash */, 164 | D218AAB220013D56004A252D /* Extensions */, 165 | D218AAB620013D56004A252D /* Coin */, 166 | D218AABC20013D56004A252D /* Engine */, 167 | ); 168 | path = Crypto; 169 | sourceTree = ""; 170 | }; 171 | D218AAAC20013D56004A252D /* Hash */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | D218AAAD20013D56004A252D /* keccak */, 175 | ); 176 | path = Hash; 177 | sourceTree = ""; 178 | }; 179 | D218AAAD20013D56004A252D /* keccak */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | D218AAAE20013D56004A252D /* KeccakHash.swift */, 183 | D218AAAF20013D56004A252D /* sha3.h */, 184 | D218AAB120013D56004A252D /* sha3.c */, 185 | ); 186 | path = keccak; 187 | sourceTree = ""; 188 | }; 189 | D218AAB220013D56004A252D /* Extensions */ = { 190 | isa = PBXGroup; 191 | children = ( 192 | D218AAB320013D56004A252D /* String+Extensions.swift */, 193 | D218AAB420013D56004A252D /* UnsafePointer+Extensions.swift */, 194 | D218AAB520013D56004A252D /* Data+Extensions.swift */, 195 | ); 196 | path = Extensions; 197 | sourceTree = ""; 198 | }; 199 | D218AAB620013D56004A252D /* Coin */ = { 200 | isa = PBXGroup; 201 | children = ( 202 | D218AAB720013D56004A252D /* Bitcoin.swift */, 203 | D218AAB820013D56004A252D /* Ripple.swift */, 204 | D218AAB920013D56004A252D /* Ethereum.swift */, 205 | D218AABA20013D56004A252D /* CoinAware.swift */, 206 | D218AABB20013D56004A252D /* Account.swift */, 207 | D24EF2922002D78E002ECD08 /* Monero.swift */, 208 | ); 209 | path = Coin; 210 | sourceTree = ""; 211 | }; 212 | D218AABC20013D56004A252D /* Engine */ = { 213 | isa = PBXGroup; 214 | children = ( 215 | D218AABD20013D56004A252D /* CoinList.swift */, 216 | D218AABE20013D56004A252D /* KeyPairGenerator.swift */, 217 | D218AABF20013D56004A252D /* Manager.swift */, 218 | D218AAC020013D56004A252D /* SwiftBaseX.swift */, 219 | D218AAC120013D56004A252D /* Pay2ScriptHashGenerator.swift */, 220 | D218AAC220013D56004A252D /* InternalError.swift */, 221 | D218AAC320013D56004A252D /* EthereumGenerator.swift */, 222 | D218AAC420013D56004A252D /* WalletImportFormatGenerator.swift */, 223 | D218AAC520013D56004A252D /* PublicKeyCompressor.swift */, 224 | D218AAC620013D56004A252D /* RippleGenerator.swift */, 225 | D218AAC720013D56004A252D /* Task.swift */, 226 | D218AAC820013D56004A252D /* Pay2PubKeyHashGenerator.swift */, 227 | D24EF2902002D770002ECD08 /* MoneroGenerator.swift */, 228 | ); 229 | path = Engine; 230 | sourceTree = ""; 231 | }; 232 | D218AAC920013D56004A252D /* Utils */ = { 233 | isa = PBXGroup; 234 | children = ( 235 | D218AAE120013DB8004A252D /* QRCodeGenerator.swift */, 236 | ); 237 | path = Utils; 238 | sourceTree = ""; 239 | }; 240 | D218E9061FE2C37800438A19 = { 241 | isa = PBXGroup; 242 | children = ( 243 | D218E9111FE2C37800438A19 /* AddressGenerator */, 244 | D218E9241FE2C37800438A19 /* AddressGeneratorTests */, 245 | D218E9101FE2C37800438A19 /* Products */, 246 | 7E6D7807200511B08B797FC8 /* Pods */, 247 | 902F97D5B227231DBE1B88C0 /* Frameworks */, 248 | ); 249 | sourceTree = ""; 250 | }; 251 | D218E9101FE2C37800438A19 /* Products */ = { 252 | isa = PBXGroup; 253 | children = ( 254 | D218E90F1FE2C37800438A19 /* AddressGenerator.app */, 255 | D218E9211FE2C37800438A19 /* AddressGeneratorTests.xctest */, 256 | ); 257 | name = Products; 258 | sourceTree = ""; 259 | }; 260 | D218E9111FE2C37800438A19 /* AddressGenerator */ = { 261 | isa = PBXGroup; 262 | children = ( 263 | D25570981FEBCDD800AA443F /* Views */, 264 | D25570951FEBCDAC00AA443F /* Controllers */, 265 | D218E93E1FE2C3F700438A19 /* Library */, 266 | D218E9121FE2C37800438A19 /* AppDelegate.swift */, 267 | D218E9161FE2C37800438A19 /* Assets.xcassets */, 268 | D218E9181FE2C37800438A19 /* Main.storyboard */, 269 | D218E91B1FE2C37800438A19 /* Info.plist */, 270 | D218E91C1FE2C37800438A19 /* AddressGenerator.entitlements */, 271 | ); 272 | path = AddressGenerator; 273 | sourceTree = ""; 274 | }; 275 | D218E9241FE2C37800438A19 /* AddressGeneratorTests */ = { 276 | isa = PBXGroup; 277 | children = ( 278 | D218E9251FE2C37800438A19 /* AddressGeneratorTests.swift */, 279 | D218E9271FE2C37900438A19 /* Info.plist */, 280 | D2EDF5271FEACC01009BF07B /* KeccakHashTests.swift */, 281 | D2EDF5291FEACC0D009BF07B /* KeyPairGeneratorTests.swift */, 282 | D2EDF52B1FEACC27009BF07B /* DataExtensionsTests.swift */, 283 | D2EDF52D1FEACC5A009BF07B /* WalletImportGeneratorTests.swift */, 284 | D2EDF5331FEAD20B009BF07B /* EthereumGeneratorTests.swift */, 285 | D2EDF5421FEAE06C009BF07B /* CoinListTests.swift */, 286 | D218AAA72001378A004A252D /* RippleGeneratorTests.swift */, 287 | D218AAA920013822004A252D /* PublicKeyCompressorTests.swift */, 288 | ); 289 | path = AddressGeneratorTests; 290 | sourceTree = ""; 291 | }; 292 | D218E93E1FE2C3F700438A19 /* Library */ = { 293 | isa = PBXGroup; 294 | children = ( 295 | D218AAE020013D87004A252D /* AddressGenerator-Bridging-Header.h */, 296 | D218AAAB20013D56004A252D /* Crypto */, 297 | D218AAC920013D56004A252D /* Utils */, 298 | ); 299 | path = Library; 300 | sourceTree = ""; 301 | }; 302 | D25570951FEBCDAC00AA443F /* Controllers */ = { 303 | isa = PBXGroup; 304 | children = ( 305 | D255709D1FEBD2B100AA443F /* MainController.swift */, 306 | D25570A11FEBD70900AA443F /* BaseController.swift */, 307 | D25570961FEBCDBD00AA443F /* CoinsController.swift */, 308 | D25570991FEBCDE600AA443F /* AccountController.swift */, 309 | D255709F1FEBD51800AA443F /* WindowController.swift */, 310 | ); 311 | path = Controllers; 312 | sourceTree = ""; 313 | }; 314 | D25570981FEBCDD800AA443F /* Views */ = { 315 | isa = PBXGroup; 316 | children = ( 317 | D255709B1FEBD07400AA443F /* Label.swift */, 318 | D25570A31FEBDCCD00AA443F /* Cell.swift */, 319 | ); 320 | path = Views; 321 | sourceTree = ""; 322 | }; 323 | /* End PBXGroup section */ 324 | 325 | /* Begin PBXNativeTarget section */ 326 | D218E90E1FE2C37800438A19 /* AddressGenerator */ = { 327 | isa = PBXNativeTarget; 328 | buildConfigurationList = D218E9351FE2C37900438A19 /* Build configuration list for PBXNativeTarget "AddressGenerator" */; 329 | buildPhases = ( 330 | 241A9CA3E85A86CB0C39AFED /* [CP] Check Pods Manifest.lock */, 331 | D218E90B1FE2C37800438A19 /* Sources */, 332 | D218E90C1FE2C37800438A19 /* Frameworks */, 333 | D218E90D1FE2C37800438A19 /* Resources */, 334 | 433BA4FB4B2DCF8BD5234C85 /* [CP] Embed Pods Frameworks */, 335 | ); 336 | buildRules = ( 337 | ); 338 | dependencies = ( 339 | ); 340 | name = AddressGenerator; 341 | productName = AddressGenerator; 342 | productReference = D218E90F1FE2C37800438A19 /* AddressGenerator.app */; 343 | productType = "com.apple.product-type.application"; 344 | }; 345 | D218E9201FE2C37800438A19 /* AddressGeneratorTests */ = { 346 | isa = PBXNativeTarget; 347 | buildConfigurationList = D218E9381FE2C37900438A19 /* Build configuration list for PBXNativeTarget "AddressGeneratorTests" */; 348 | buildPhases = ( 349 | D218E91D1FE2C37800438A19 /* Sources */, 350 | D218E91E1FE2C37800438A19 /* Frameworks */, 351 | D218E91F1FE2C37800438A19 /* Resources */, 352 | ); 353 | buildRules = ( 354 | ); 355 | dependencies = ( 356 | D218E9231FE2C37800438A19 /* PBXTargetDependency */, 357 | ); 358 | name = AddressGeneratorTests; 359 | productName = AddressGeneratorTests; 360 | productReference = D218E9211FE2C37800438A19 /* AddressGeneratorTests.xctest */; 361 | productType = "com.apple.product-type.bundle.unit-test"; 362 | }; 363 | /* End PBXNativeTarget section */ 364 | 365 | /* Begin PBXProject section */ 366 | D218E9071FE2C37800438A19 /* Project object */ = { 367 | isa = PBXProject; 368 | attributes = { 369 | LastSwiftUpdateCheck = 0920; 370 | LastUpgradeCheck = 1010; 371 | ORGANIZATIONNAME = "Khoa Pham"; 372 | TargetAttributes = { 373 | D218E90E1FE2C37800438A19 = { 374 | CreatedOnToolsVersion = 9.2; 375 | LastSwiftMigration = 0920; 376 | ProvisioningStyle = Automatic; 377 | SystemCapabilities = { 378 | com.apple.HardenedRuntime = { 379 | enabled = 1; 380 | }; 381 | }; 382 | }; 383 | D218E9201FE2C37800438A19 = { 384 | CreatedOnToolsVersion = 9.2; 385 | ProvisioningStyle = Automatic; 386 | TestTargetID = D218E90E1FE2C37800438A19; 387 | }; 388 | }; 389 | }; 390 | buildConfigurationList = D218E90A1FE2C37800438A19 /* Build configuration list for PBXProject "AddressGenerator" */; 391 | compatibilityVersion = "Xcode 8.0"; 392 | developmentRegion = en; 393 | hasScannedForEncodings = 0; 394 | knownRegions = ( 395 | en, 396 | Base, 397 | ); 398 | mainGroup = D218E9061FE2C37800438A19; 399 | productRefGroup = D218E9101FE2C37800438A19 /* Products */; 400 | projectDirPath = ""; 401 | projectRoot = ""; 402 | targets = ( 403 | D218E90E1FE2C37800438A19 /* AddressGenerator */, 404 | D218E9201FE2C37800438A19 /* AddressGeneratorTests */, 405 | ); 406 | }; 407 | /* End PBXProject section */ 408 | 409 | /* Begin PBXResourcesBuildPhase section */ 410 | D218E90D1FE2C37800438A19 /* Resources */ = { 411 | isa = PBXResourcesBuildPhase; 412 | buildActionMask = 2147483647; 413 | files = ( 414 | D218E9171FE2C37800438A19 /* Assets.xcassets in Resources */, 415 | D218E91A1FE2C37800438A19 /* Main.storyboard in Resources */, 416 | ); 417 | runOnlyForDeploymentPostprocessing = 0; 418 | }; 419 | D218E91F1FE2C37800438A19 /* Resources */ = { 420 | isa = PBXResourcesBuildPhase; 421 | buildActionMask = 2147483647; 422 | files = ( 423 | ); 424 | runOnlyForDeploymentPostprocessing = 0; 425 | }; 426 | /* End PBXResourcesBuildPhase section */ 427 | 428 | /* Begin PBXShellScriptBuildPhase section */ 429 | 241A9CA3E85A86CB0C39AFED /* [CP] Check Pods Manifest.lock */ = { 430 | isa = PBXShellScriptBuildPhase; 431 | buildActionMask = 2147483647; 432 | files = ( 433 | ); 434 | inputPaths = ( 435 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 436 | "${PODS_ROOT}/Manifest.lock", 437 | ); 438 | name = "[CP] Check Pods Manifest.lock"; 439 | outputPaths = ( 440 | "$(DERIVED_FILE_DIR)/Pods-AddressGenerator-checkManifestLockResult.txt", 441 | ); 442 | runOnlyForDeploymentPostprocessing = 0; 443 | shellPath = /bin/sh; 444 | 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"; 445 | showEnvVarsInLog = 0; 446 | }; 447 | 433BA4FB4B2DCF8BD5234C85 /* [CP] Embed Pods Frameworks */ = { 448 | isa = PBXShellScriptBuildPhase; 449 | buildActionMask = 2147483647; 450 | files = ( 451 | ); 452 | inputPaths = ( 453 | "${PODS_ROOT}/Target Support Files/Pods-AddressGenerator/Pods-AddressGenerator-frameworks.sh", 454 | "${BUILT_PRODUCTS_DIR}/Anchors/Anchors.framework", 455 | "${BUILT_PRODUCTS_DIR}/Omnia/Omnia.framework", 456 | ); 457 | name = "[CP] Embed Pods Frameworks"; 458 | outputPaths = ( 459 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Anchors.framework", 460 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Omnia.framework", 461 | ); 462 | runOnlyForDeploymentPostprocessing = 0; 463 | shellPath = /bin/sh; 464 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AddressGenerator/Pods-AddressGenerator-frameworks.sh\"\n"; 465 | showEnvVarsInLog = 0; 466 | }; 467 | /* End PBXShellScriptBuildPhase section */ 468 | 469 | /* Begin PBXSourcesBuildPhase section */ 470 | D218E90B1FE2C37800438A19 /* Sources */ = { 471 | isa = PBXSourcesBuildPhase; 472 | buildActionMask = 2147483647; 473 | files = ( 474 | D218AADE20013D56004A252D /* Task.swift in Sources */, 475 | D218AAD820013D56004A252D /* Pay2ScriptHashGenerator.swift in Sources */, 476 | D218AACB20013D56004A252D /* sha3.c in Sources */, 477 | D218AAD520013D56004A252D /* KeyPairGenerator.swift in Sources */, 478 | D218AACC20013D56004A252D /* String+Extensions.swift in Sources */, 479 | D218AACF20013D56004A252D /* Bitcoin.swift in Sources */, 480 | D218AAD920013D56004A252D /* InternalError.swift in Sources */, 481 | D24EF2912002D770002ECD08 /* MoneroGenerator.swift in Sources */, 482 | D218AAD620013D56004A252D /* Manager.swift in Sources */, 483 | D25570A41FEBDCCD00AA443F /* Cell.swift in Sources */, 484 | D218AAD220013D56004A252D /* CoinAware.swift in Sources */, 485 | D24EF2932002D78E002ECD08 /* Monero.swift in Sources */, 486 | D218AAD320013D56004A252D /* Account.swift in Sources */, 487 | D218AACA20013D56004A252D /* KeccakHash.swift in Sources */, 488 | D25570A01FEBD51800AA443F /* WindowController.swift in Sources */, 489 | D218AAD420013D56004A252D /* CoinList.swift in Sources */, 490 | D218AAE220013DB8004A252D /* QRCodeGenerator.swift in Sources */, 491 | D255709A1FEBCDE600AA443F /* AccountController.swift in Sources */, 492 | D218AADB20013D56004A252D /* WalletImportFormatGenerator.swift in Sources */, 493 | D218AADA20013D56004A252D /* EthereumGenerator.swift in Sources */, 494 | D218E9131FE2C37800438A19 /* AppDelegate.swift in Sources */, 495 | D218AAD720013D56004A252D /* SwiftBaseX.swift in Sources */, 496 | D218AAD120013D56004A252D /* Ethereum.swift in Sources */, 497 | D218AADD20013D56004A252D /* RippleGenerator.swift in Sources */, 498 | D218AACE20013D56004A252D /* Data+Extensions.swift in Sources */, 499 | D218AACD20013D56004A252D /* UnsafePointer+Extensions.swift in Sources */, 500 | D255709C1FEBD07400AA443F /* Label.swift in Sources */, 501 | D25570A21FEBD70900AA443F /* BaseController.swift in Sources */, 502 | D218AADF20013D56004A252D /* Pay2PubKeyHashGenerator.swift in Sources */, 503 | D218AAD020013D56004A252D /* Ripple.swift in Sources */, 504 | D255709E1FEBD2B200AA443F /* MainController.swift in Sources */, 505 | D218AADC20013D56004A252D /* PublicKeyCompressor.swift in Sources */, 506 | D25570971FEBCDBD00AA443F /* CoinsController.swift in Sources */, 507 | ); 508 | runOnlyForDeploymentPostprocessing = 0; 509 | }; 510 | D218E91D1FE2C37800438A19 /* Sources */ = { 511 | isa = PBXSourcesBuildPhase; 512 | buildActionMask = 2147483647; 513 | files = ( 514 | D218E9261FE2C37800438A19 /* AddressGeneratorTests.swift in Sources */, 515 | D2EDF5431FEAE06C009BF07B /* CoinListTests.swift in Sources */, 516 | D2EDF52C1FEACC27009BF07B /* DataExtensionsTests.swift in Sources */, 517 | D218AAA82001378A004A252D /* RippleGeneratorTests.swift in Sources */, 518 | D2EDF5341FEAD20B009BF07B /* EthereumGeneratorTests.swift in Sources */, 519 | D2EDF52A1FEACC0D009BF07B /* KeyPairGeneratorTests.swift in Sources */, 520 | D2EDF52E1FEACC5A009BF07B /* WalletImportGeneratorTests.swift in Sources */, 521 | D218AAAA20013822004A252D /* PublicKeyCompressorTests.swift in Sources */, 522 | D2EDF5281FEACC01009BF07B /* KeccakHashTests.swift in Sources */, 523 | ); 524 | runOnlyForDeploymentPostprocessing = 0; 525 | }; 526 | /* End PBXSourcesBuildPhase section */ 527 | 528 | /* Begin PBXTargetDependency section */ 529 | D218E9231FE2C37800438A19 /* PBXTargetDependency */ = { 530 | isa = PBXTargetDependency; 531 | target = D218E90E1FE2C37800438A19 /* AddressGenerator */; 532 | targetProxy = D218E9221FE2C37800438A19 /* PBXContainerItemProxy */; 533 | }; 534 | /* End PBXTargetDependency section */ 535 | 536 | /* Begin PBXVariantGroup section */ 537 | D218E9181FE2C37800438A19 /* Main.storyboard */ = { 538 | isa = PBXVariantGroup; 539 | children = ( 540 | D218E9191FE2C37800438A19 /* Base */, 541 | ); 542 | name = Main.storyboard; 543 | sourceTree = ""; 544 | }; 545 | /* End PBXVariantGroup section */ 546 | 547 | /* Begin XCBuildConfiguration section */ 548 | D218E9331FE2C37900438A19 /* Debug */ = { 549 | isa = XCBuildConfiguration; 550 | buildSettings = { 551 | ALWAYS_SEARCH_USER_PATHS = NO; 552 | CLANG_ANALYZER_NONNULL = YES; 553 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 554 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 555 | CLANG_CXX_LIBRARY = "libc++"; 556 | CLANG_ENABLE_MODULES = YES; 557 | CLANG_ENABLE_OBJC_ARC = YES; 558 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 559 | CLANG_WARN_BOOL_CONVERSION = YES; 560 | CLANG_WARN_COMMA = YES; 561 | CLANG_WARN_CONSTANT_CONVERSION = YES; 562 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 563 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 564 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 565 | CLANG_WARN_EMPTY_BODY = YES; 566 | CLANG_WARN_ENUM_CONVERSION = YES; 567 | CLANG_WARN_INFINITE_RECURSION = YES; 568 | CLANG_WARN_INT_CONVERSION = YES; 569 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 570 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 571 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 572 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 573 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 574 | CLANG_WARN_STRICT_PROTOTYPES = YES; 575 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 576 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 577 | CLANG_WARN_UNREACHABLE_CODE = YES; 578 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 579 | CODE_SIGN_IDENTITY = "-"; 580 | COPY_PHASE_STRIP = NO; 581 | DEBUG_INFORMATION_FORMAT = dwarf; 582 | ENABLE_STRICT_OBJC_MSGSEND = YES; 583 | ENABLE_TESTABILITY = YES; 584 | GCC_C_LANGUAGE_STANDARD = gnu11; 585 | GCC_DYNAMIC_NO_PIC = NO; 586 | GCC_NO_COMMON_BLOCKS = YES; 587 | GCC_OPTIMIZATION_LEVEL = 0; 588 | GCC_PREPROCESSOR_DEFINITIONS = ( 589 | "DEBUG=1", 590 | "$(inherited)", 591 | ); 592 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 593 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 594 | GCC_WARN_UNDECLARED_SELECTOR = YES; 595 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 596 | GCC_WARN_UNUSED_FUNCTION = YES; 597 | GCC_WARN_UNUSED_VARIABLE = YES; 598 | MACOSX_DEPLOYMENT_TARGET = 10.13; 599 | MTL_ENABLE_DEBUG_INFO = YES; 600 | ONLY_ACTIVE_ARCH = YES; 601 | SDKROOT = macosx; 602 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 603 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 604 | SWIFT_VERSION = 4.2; 605 | }; 606 | name = Debug; 607 | }; 608 | D218E9341FE2C37900438A19 /* Release */ = { 609 | isa = XCBuildConfiguration; 610 | buildSettings = { 611 | ALWAYS_SEARCH_USER_PATHS = NO; 612 | CLANG_ANALYZER_NONNULL = YES; 613 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 614 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 615 | CLANG_CXX_LIBRARY = "libc++"; 616 | CLANG_ENABLE_MODULES = YES; 617 | CLANG_ENABLE_OBJC_ARC = YES; 618 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 619 | CLANG_WARN_BOOL_CONVERSION = YES; 620 | CLANG_WARN_COMMA = YES; 621 | CLANG_WARN_CONSTANT_CONVERSION = YES; 622 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 623 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 624 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 625 | CLANG_WARN_EMPTY_BODY = YES; 626 | CLANG_WARN_ENUM_CONVERSION = YES; 627 | CLANG_WARN_INFINITE_RECURSION = YES; 628 | CLANG_WARN_INT_CONVERSION = YES; 629 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 630 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 631 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 632 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 633 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 634 | CLANG_WARN_STRICT_PROTOTYPES = YES; 635 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 636 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 637 | CLANG_WARN_UNREACHABLE_CODE = YES; 638 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 639 | CODE_SIGN_IDENTITY = "-"; 640 | COPY_PHASE_STRIP = NO; 641 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 642 | ENABLE_NS_ASSERTIONS = NO; 643 | ENABLE_STRICT_OBJC_MSGSEND = YES; 644 | GCC_C_LANGUAGE_STANDARD = gnu11; 645 | GCC_NO_COMMON_BLOCKS = YES; 646 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 647 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 648 | GCC_WARN_UNDECLARED_SELECTOR = YES; 649 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 650 | GCC_WARN_UNUSED_FUNCTION = YES; 651 | GCC_WARN_UNUSED_VARIABLE = YES; 652 | MACOSX_DEPLOYMENT_TARGET = 10.13; 653 | MTL_ENABLE_DEBUG_INFO = NO; 654 | SDKROOT = macosx; 655 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 656 | SWIFT_VERSION = 4.2; 657 | }; 658 | name = Release; 659 | }; 660 | D218E9361FE2C37900438A19 /* Debug */ = { 661 | isa = XCBuildConfiguration; 662 | baseConfigurationReference = 5063F40B8222686F291286C0 /* Pods-AddressGenerator.debug.xcconfig */; 663 | buildSettings = { 664 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 665 | CLANG_ENABLE_MODULES = YES; 666 | CODE_SIGN_ENTITLEMENTS = AddressGenerator/AddressGenerator.entitlements; 667 | CODE_SIGN_IDENTITY = "Mac Developer"; 668 | CODE_SIGN_STYLE = Automatic; 669 | COMBINE_HIDPI_IMAGES = YES; 670 | DEVELOPMENT_TEAM = T78DK947F2; 671 | ENABLE_HARDENED_RUNTIME = YES; 672 | INFOPLIST_FILE = AddressGenerator/Info.plist; 673 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 674 | MACOSX_DEPLOYMENT_TARGET = 10.11; 675 | PRODUCT_BUNDLE_IDENTIFIER = com.onmyway133.AddressGenerator; 676 | PRODUCT_NAME = "$(TARGET_NAME)"; 677 | PROVISIONING_PROFILE_SPECIFIER = ""; 678 | SWIFT_OBJC_BRIDGING_HEADER = "AddressGenerator/Library/AddressGenerator-Bridging-Header.h"; 679 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 680 | }; 681 | name = Debug; 682 | }; 683 | D218E9371FE2C37900438A19 /* Release */ = { 684 | isa = XCBuildConfiguration; 685 | baseConfigurationReference = 9872C9EAB1987817A1ADC5ED /* Pods-AddressGenerator.release.xcconfig */; 686 | buildSettings = { 687 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 688 | CLANG_ENABLE_MODULES = YES; 689 | CODE_SIGN_ENTITLEMENTS = AddressGenerator/AddressGenerator.entitlements; 690 | CODE_SIGN_IDENTITY = "Mac Developer"; 691 | CODE_SIGN_STYLE = Automatic; 692 | COMBINE_HIDPI_IMAGES = YES; 693 | DEVELOPMENT_TEAM = T78DK947F2; 694 | ENABLE_HARDENED_RUNTIME = YES; 695 | INFOPLIST_FILE = AddressGenerator/Info.plist; 696 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 697 | MACOSX_DEPLOYMENT_TARGET = 10.11; 698 | PRODUCT_BUNDLE_IDENTIFIER = com.onmyway133.AddressGenerator; 699 | PRODUCT_NAME = "$(TARGET_NAME)"; 700 | PROVISIONING_PROFILE_SPECIFIER = ""; 701 | SWIFT_OBJC_BRIDGING_HEADER = "AddressGenerator/Library/AddressGenerator-Bridging-Header.h"; 702 | }; 703 | name = Release; 704 | }; 705 | D218E9391FE2C37900438A19 /* Debug */ = { 706 | isa = XCBuildConfiguration; 707 | buildSettings = { 708 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 709 | BUNDLE_LOADER = "$(TEST_HOST)"; 710 | CODE_SIGN_STYLE = Automatic; 711 | COMBINE_HIDPI_IMAGES = YES; 712 | INFOPLIST_FILE = AddressGeneratorTests/Info.plist; 713 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 714 | PRODUCT_BUNDLE_IDENTIFIER = com.onmyway133.AddressGeneratorTests; 715 | PRODUCT_NAME = "$(TARGET_NAME)"; 716 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AddressGenerator.app/Contents/MacOS/AddressGenerator"; 717 | }; 718 | name = Debug; 719 | }; 720 | D218E93A1FE2C37900438A19 /* Release */ = { 721 | isa = XCBuildConfiguration; 722 | buildSettings = { 723 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 724 | BUNDLE_LOADER = "$(TEST_HOST)"; 725 | CODE_SIGN_STYLE = Automatic; 726 | COMBINE_HIDPI_IMAGES = YES; 727 | INFOPLIST_FILE = AddressGeneratorTests/Info.plist; 728 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 729 | PRODUCT_BUNDLE_IDENTIFIER = com.onmyway133.AddressGeneratorTests; 730 | PRODUCT_NAME = "$(TARGET_NAME)"; 731 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/AddressGenerator.app/Contents/MacOS/AddressGenerator"; 732 | }; 733 | name = Release; 734 | }; 735 | /* End XCBuildConfiguration section */ 736 | 737 | /* Begin XCConfigurationList section */ 738 | D218E90A1FE2C37800438A19 /* Build configuration list for PBXProject "AddressGenerator" */ = { 739 | isa = XCConfigurationList; 740 | buildConfigurations = ( 741 | D218E9331FE2C37900438A19 /* Debug */, 742 | D218E9341FE2C37900438A19 /* Release */, 743 | ); 744 | defaultConfigurationIsVisible = 0; 745 | defaultConfigurationName = Release; 746 | }; 747 | D218E9351FE2C37900438A19 /* Build configuration list for PBXNativeTarget "AddressGenerator" */ = { 748 | isa = XCConfigurationList; 749 | buildConfigurations = ( 750 | D218E9361FE2C37900438A19 /* Debug */, 751 | D218E9371FE2C37900438A19 /* Release */, 752 | ); 753 | defaultConfigurationIsVisible = 0; 754 | defaultConfigurationName = Release; 755 | }; 756 | D218E9381FE2C37900438A19 /* Build configuration list for PBXNativeTarget "AddressGeneratorTests" */ = { 757 | isa = XCConfigurationList; 758 | buildConfigurations = ( 759 | D218E9391FE2C37900438A19 /* Debug */, 760 | D218E93A1FE2C37900438A19 /* Release */, 761 | ); 762 | defaultConfigurationIsVisible = 0; 763 | defaultConfigurationName = Release; 764 | }; 765 | /* End XCConfigurationList section */ 766 | }; 767 | rootObject = D218E9071FE2C37800438A19 /* Project object */; 768 | } 769 | -------------------------------------------------------------------------------- /AddressGenerator.xcodeproj/xcshareddata/xcschemes/AddressGenerator.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /AddressGenerator/AddressGenerator.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /AddressGenerator/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 14.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | func applicationDidFinishLaunching(_ aNotification: Notification) { 15 | // Insert code here to initialize your application 16 | } 17 | 18 | func applicationWillTerminate(_ aNotification: Notification) { 19 | // Insert code here to tear down your application 20 | } 21 | 22 | func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 23 | return true 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon_16@1x.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon_16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon_32@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon_32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon_128@1x.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon_128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon_256@1x.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon_256@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon_512@1x.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon_512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_128@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_128@1x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_128@2x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_16@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_16@1x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_16@2x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_256@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_256@1x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_256@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_256@2x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_32@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_32@1x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_32@2x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_512@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_512@1x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/AppIcon.appiconset/icon_512@2x.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Bitcoin.imageset/Bitcoin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/Coins/Bitcoin.imageset/Bitcoin.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Bitcoin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Bitcoin.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Dash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Dash.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Dash.imageset/Dash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/Coins/Dash.imageset/Dash.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Ethereum.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Ethereum.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Ethereum.imageset/Ethereum.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/Coins/Ethereum.imageset/Ethereum.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Litecoin.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Litecoin.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Litecoin.imageset/Litecoin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/Coins/Litecoin.imageset/Litecoin.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Others.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "Others.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Others.imageset/Others.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/Coins/Others.imageset/Others.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Ripple.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "ripple.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Coins/Ripple.imageset/ripple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/AddressGenerator/Assets.xcassets/Coins/Ripple.imageset/ripple.png -------------------------------------------------------------------------------- /AddressGenerator/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /AddressGenerator/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /AddressGenerator/Controllers/AccountController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AccountController.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 21.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | import Anchors 11 | 12 | final class AccountController: BaseController { 13 | private let coinNameLabel = Label() 14 | private let button = NSButton() 15 | private let addressImageView = NSImageView() 16 | 17 | private let addressLabel = Label() 18 | private let addressValueLabel = Label() 19 | 20 | private let publicKeyLabel = Label() 21 | private let publicKeyValueLabel = Label() 22 | 23 | private let privateKeyLabel = Label() 24 | private let privateKeyValueLabel = Label() 25 | 26 | private let wifLabel = Label() 27 | private let wifValueLabel = Label() 28 | 29 | private let aboutButton = NSButton() 30 | private let gitHubUrl = "https://github.com/onmyway133/AddressGenerator" 31 | 32 | private let progressIndicator = NSProgressIndicator() 33 | 34 | var coin: CoinAware! { 35 | didSet { 36 | coinNameLabel.stringValue = coin.name 37 | clear() 38 | } 39 | } 40 | 41 | override func viewDidLoad() { 42 | super.viewDidLoad() 43 | 44 | setup() 45 | aboutButton.isHidden = true 46 | } 47 | 48 | private func setup() { 49 | view.e_addSubviews([ 50 | coinNameLabel, button, addressImageView, 51 | addressLabel, addressValueLabel, 52 | publicKeyLabel, publicKeyValueLabel, 53 | privateKeyLabel, privateKeyValueLabel, 54 | wifLabel, wifValueLabel, 55 | aboutButton, 56 | progressIndicator 57 | ]) 58 | 59 | coinNameLabel.font = NSFont.systemFont(ofSize: 25, weight: .bold) 60 | [addressLabel, publicKeyLabel, privateKeyLabel, wifLabel].forEach { 61 | $0.font = NSFont.systemFont(ofSize: 15, weight: .semibold) 62 | } 63 | [addressValueLabel, publicKeyValueLabel, privateKeyValueLabel, wifValueLabel].forEach { 64 | $0.font = NSFont.systemFont(ofSize: 15) 65 | $0.textColor = NSColor(e_hex: "#e67e22") 66 | $0.isSelectable = true 67 | } 68 | 69 | addressLabel.stringValue = "Address" 70 | publicKeyLabel.stringValue = "Public Key" 71 | privateKeyLabel.stringValue = "Private Key" 72 | wifLabel.stringValue = "Private Key (Wallet Import Format)" 73 | 74 | button.title = "Generate" 75 | button.target = self 76 | button.action = #selector(generateButtonTouched) 77 | 78 | progressIndicator.style = .spinning 79 | progressIndicator.controlTint = .blueControlTint 80 | progressIndicator.startAnimation(nil) 81 | progressIndicator.alphaValue = 0 82 | 83 | do { 84 | let attributeString = NSAttributedString( 85 | string: "GitHub: \(gitHubUrl)", 86 | attributes: [ 87 | .foregroundColor: NSColor(e_hex: "#f1c40f") 88 | ] 89 | ) 90 | 91 | aboutButton.attributedTitle = attributeString 92 | aboutButton.isBordered = false 93 | aboutButton.target = self 94 | aboutButton.action = #selector(about) 95 | } 96 | 97 | setupConstraints() 98 | } 99 | 100 | @objc private func generateButtonTouched() { 101 | progressIndicator.alphaValue = 1 102 | DispatchQueue.global().async { 103 | do { 104 | let account = try self.coin.generate() 105 | DispatchQueue.main.async { 106 | self.update(account: account) 107 | self.progressIndicator.alphaValue = 0 108 | } 109 | } catch {} 110 | } 111 | } 112 | 113 | private func clear() { 114 | addressValueLabel.stringValue = "" 115 | publicKeyValueLabel.stringValue = "" 116 | privateKeyValueLabel.stringValue = "" 117 | wifValueLabel.stringValue = "" 118 | addressImageView.image = nil 119 | } 120 | 121 | private func update(account: Account) { 122 | addressValueLabel.stringValue = account.address 123 | publicKeyValueLabel.stringValue = account.rawPublicKey 124 | privateKeyValueLabel.stringValue = account.rawPrivateKey 125 | wifValueLabel.stringValue = account.walletImportFormat ?? "" 126 | 127 | addressImageView.image = QRCodeGenerator().generate( 128 | string: account.address, 129 | size: addressImageView.frame.size 130 | ) 131 | } 132 | 133 | @objc private func about() { 134 | NSWorkspace.shared.open(URL(string: gitHubUrl)!) 135 | } 136 | 137 | private func setupConstraints() { 138 | activate( 139 | coinNameLabel.anchor.top.constant(20), 140 | coinNameLabel.anchor.centerX, 141 | 142 | button.anchor.top.equal.to(coinNameLabel.anchor.bottom).constant(10), 143 | button.anchor.centerX, 144 | button.anchor.width.equal.to(100), 145 | button.anchor.height.equal.to(30), 146 | 147 | progressIndicator.anchor.left.equal.to(button.anchor.right).constant(10), 148 | progressIndicator.anchor.centerY.equal.to(button.anchor.centerY), 149 | 150 | addressImageView.anchor.top.equal.to(button.anchor.bottom).constant(30), 151 | addressImageView.anchor.centerX, 152 | addressImageView.anchor.width.equal.to(200), 153 | addressImageView.anchor.height.ratio(1), 154 | 155 | addressLabel.anchor.top.equal 156 | .to(addressImageView.anchor.bottom).constant(20), 157 | addressLabel.anchor.centerX, 158 | 159 | addressValueLabel.anchor.top.equal 160 | .to(addressLabel.anchor.bottom).constant(5), 161 | addressValueLabel.anchor.centerX, 162 | 163 | publicKeyLabel.anchor.top.equal 164 | .to(addressValueLabel.anchor.bottom).constant(20), 165 | publicKeyLabel.anchor.left.constant(10), 166 | 167 | publicKeyValueLabel.anchor.top.equal 168 | .to(publicKeyLabel.anchor.bottom).constant(5), 169 | publicKeyValueLabel.anchor.left.constant(10), 170 | 171 | privateKeyLabel.anchor.top.equal 172 | .to(publicKeyValueLabel.anchor.bottom).constant(10), 173 | privateKeyLabel.anchor.left.constant(10), 174 | 175 | privateKeyValueLabel.anchor.top.equal 176 | .to(privateKeyLabel.anchor.bottom).constant(5), 177 | privateKeyValueLabel.anchor.left.constant(10), 178 | 179 | wifLabel.anchor.top.equal 180 | .to(privateKeyValueLabel.anchor.bottom).constant(10), 181 | wifLabel.anchor.left.constant(10), 182 | 183 | wifValueLabel.anchor.top.equal 184 | .to(wifLabel.anchor.bottom).constant(5), 185 | wifValueLabel.anchor.left.constant(10) 186 | ) 187 | 188 | activate( 189 | aboutButton.anchor.top.right 190 | ) 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /AddressGenerator/Controllers/BaseController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseController.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 21.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | 11 | class BaseController: NSViewController { 12 | override func loadView() { 13 | self.view = NSView() 14 | self.view.wantsLayer = true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AddressGenerator/Controllers/CoinsController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CoinsController.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 21.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | import Anchors 11 | 12 | final class CoinsController: BaseController, NSCollectionViewDataSource, NSCollectionViewDelegateFlowLayout { 13 | private var titleLabel: Label! 14 | private var scrollView: NSScrollView! 15 | private var collectionView: NSCollectionView! 16 | private let coins = CoinList.allCoins 17 | var select: ((CoinAware) -> Void)? 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | setup() 23 | } 24 | 25 | override func viewWillAppear() { 26 | super.viewWillAppear() 27 | 28 | selectFirstInitially() 29 | } 30 | 31 | private func selectFirstInitially() { 32 | let indexPath = IndexPath(item: 0, section: 0) 33 | let set = Set(arrayLiteral: indexPath) 34 | collectionView.selectItems(at: set, scrollPosition: .top) 35 | collectionView(collectionView, didSelectItemsAt: set) 36 | } 37 | 38 | private func setup() { 39 | do { 40 | titleLabel = Label() 41 | titleLabel.font = NSFont.systemFont(ofSize: 15, weight: .semibold) 42 | titleLabel.stringValue = "Choose currency" 43 | view.addSubview(titleLabel) 44 | activate( 45 | titleLabel.anchor.top.left 46 | ) 47 | } 48 | 49 | do { 50 | let layout = NSCollectionViewFlowLayout() 51 | layout.minimumLineSpacing = 4 52 | 53 | collectionView = NSCollectionView() 54 | collectionView.dataSource = self 55 | collectionView.delegate = self 56 | collectionView.collectionViewLayout = layout 57 | collectionView.allowsMultipleSelection = false 58 | collectionView.backgroundColors = [.clear] 59 | collectionView.isSelectable = true 60 | collectionView.register( 61 | Cell.self, 62 | forItemWithIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Cell") 63 | ) 64 | } 65 | 66 | do { 67 | scrollView = NSScrollView() 68 | scrollView.documentView = collectionView 69 | view.addSubview(scrollView) 70 | 71 | activate( 72 | scrollView.anchor.top.equal.to(titleLabel.anchor.bottom).constant(10), 73 | scrollView.anchor.left.bottom.right 74 | ) 75 | } 76 | } 77 | 78 | // MARK: - NSCollectionViewDataSource 79 | 80 | func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { 81 | return coins.count 82 | } 83 | 84 | func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem { 85 | let cell = collectionView.makeItem( 86 | withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "Cell"), 87 | for: indexPath 88 | ) as! Cell 89 | 90 | let coin = coins[indexPath.item] 91 | 92 | cell.label.stringValue = coin.name 93 | cell.coinImageView.image = 94 | NSImage(named: NSImage.Name(coin.name)) 95 | ?? NSImage(named: NSImage.Name("Others")) 96 | 97 | return cell 98 | } 99 | 100 | // MARK: - NSCollectionViewDelegateFlowLayout 101 | 102 | func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set) { 103 | guard let indexPath = indexPaths.first else { 104 | return 105 | } 106 | 107 | let coin = coins[indexPath.item] 108 | select?(coin) 109 | } 110 | 111 | func collectionView(_ collectionView: NSCollectionView, layout collectionViewLayout: NSCollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> NSSize { 112 | 113 | return NSSize( 114 | width: collectionView.frame.size.width, 115 | height: 40 116 | ) 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /AddressGenerator/Controllers/MainController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 14.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Anchors 11 | 12 | final class MainController: BaseController { 13 | private let coinsController = CoinsController() 14 | private let accountController = AccountController() 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | setup() 20 | 21 | coinsController.select = { [weak self] coin in 22 | self?.handle(coin: coin) 23 | } 24 | } 25 | 26 | func setup() { 27 | addChild(coinsController) 28 | view.addSubview(coinsController.view) 29 | 30 | addChild(accountController) 31 | view.addSubview(accountController.view) 32 | 33 | activate( 34 | coinsController.view.anchor.left.constant(10), 35 | coinsController.view.anchor.top.constant(30), 36 | coinsController.view.anchor.bottom.constant(-20), 37 | 38 | coinsController.view.anchor.right.equal 39 | .to(accountController.view.anchor.left).constant(-20), 40 | coinsController.view.anchor.width.equal 41 | .to(accountController.view.anchor.width).multiplier(0.3), 42 | 43 | accountController.view.anchor.top.constant(10), 44 | accountController.view.anchor.right.bottom.constant(-20) 45 | ) 46 | } 47 | 48 | func handle(coin: CoinAware) { 49 | accountController.coin = coin 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /AddressGenerator/Controllers/WindowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // WindowController.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 21.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | 11 | final class WindowController: NSWindowController { 12 | override func windowDidLoad() { 13 | super.windowDidLoad() 14 | 15 | window?.setContentSize(NSSize(width: 900, height: 600)) 16 | window?.backgroundColor = NSColor(e_hex: "#333333") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /AddressGenerator/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.1 21 | CFBundleVersion 22 | 2 23 | LSApplicationCategoryType 24 | public.app-category.productivity 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2017 Khoa Pham. All rights reserved. 29 | NSMainStoryboardFile 30 | Main 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /AddressGenerator/Library/AddressGenerator-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | #import "sha3.h" 6 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Coin/Account.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Account.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 20.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Account { 12 | let rawPrivateKey: String 13 | let rawPublicKey: String 14 | let address: String 15 | let walletImportFormat: String? 16 | } 17 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Coin/Bitcoin.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// Bitcoin and similar coins 11 | class Bitcoin { 12 | let name: String 13 | let publicKeyPrefix: UInt8 14 | let privateKeyPrefix: UInt8 15 | let wifStart: String 16 | let cwifStart: String 17 | 18 | init(name: String, publicKeyPrefix: UInt8, privateKeyPrefix: UInt8, _ wifStart: String, _ cwifStart: String) { 19 | self.name = name 20 | self.publicKeyPrefix = publicKeyPrefix 21 | self.privateKeyPrefix = privateKeyPrefix 22 | self.wifStart = wifStart 23 | self.cwifStart = cwifStart 24 | } 25 | } 26 | 27 | extension Bitcoin: CoinAware { 28 | func generate() throws -> Account { 29 | let pair = try KeyPairGenerator().generate() 30 | let address = try Pay2PubKeyHashGenerator().generate(publicKey: pair.publicKey, prefix: publicKeyPrefix) 31 | let wif = try WalletImportFormatGenerator().generate(privateKey: pair.privateKey, prefix: privateKeyPrefix) 32 | 33 | return try Account( 34 | rawPrivateKey: pair.privateKey.hexDump().toString(), 35 | rawPublicKey: pair.publicKey.hexDump().toString(), 36 | address: address, 37 | walletImportFormat: wif 38 | ) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Coin/CoinAware.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | protocol CoinAware { 4 | var name: String { get } 5 | func generate() throws -> Account 6 | } 7 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Coin/Ethereum.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// Ethereum and similar coins 11 | class Ethereum { 12 | let name: String 13 | 14 | init(name: String) { 15 | self.name = name 16 | } 17 | } 18 | 19 | extension Ethereum: CoinAware { 20 | func generate() throws -> Account { 21 | let pair = try KeyPairGenerator().generate() 22 | let address = try EthereumGenerator().generate(publicKey: pair.publicKey) 23 | 24 | return try Account( 25 | rawPrivateKey: pair.privateKey.hexDump().toString(), 26 | rawPublicKey: pair.publicKey.hexDump().toString(), 27 | address: address, 28 | walletImportFormat: nil 29 | ) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Coin/Monero.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Monero.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 07.01.2018. 6 | // Copyright © 2018 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // https://getmonero.org/ 12 | struct Monero: CoinAware { 13 | let name = "Monero" 14 | 15 | func generate() throws -> Account { 16 | fatalError() 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Coin/Ripple.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Ripple.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 06.01.2018. 6 | // Copyright © 2018 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // https://ripple.com/ 12 | struct Ripple: CoinAware { 13 | let name = "Ripple" 14 | func generate() throws -> Account { 15 | let pair = try KeyPairGenerator().generate() 16 | let address = try RippleGenerator().generate(publicKey: pair.publicKey) 17 | 18 | return try Account( 19 | rawPrivateKey: pair.privateKey.hexDump().toString(), 20 | rawPublicKey: pair.publicKey.hexDump().toString(), 21 | address: address, 22 | walletImportFormat: nil 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/CoinList.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | 3 | /// Initial data from https://github.com/MichaelMure/WalletGenerator.net/blob/master/src/janin.currency.js 4 | struct CoinList { 5 | 6 | static let allCoins: [CoinAware] = { 7 | return firstCoins + coins.sorted(by: { coin1, coin2 in 8 | return coin1.name < coin2.name 9 | }) 10 | }() 11 | 12 | static let firstCoins: [CoinAware] = [ 13 | Bitcoin(name: "Bitcoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 14 | Ethereum(name: "Ethereum"), 15 | Ripple(), 16 | Bitcoin(name: "Litecoin", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 17 | Bitcoin(name: "Dash", publicKeyPrefix: 0x4c, privateKeyPrefix: 0xcc, "7", "X") 18 | ] 19 | 20 | static let coins: [CoinAware] = [ 21 | Bitcoin(name: "2GIVE", publicKeyPrefix: 0x27, privateKeyPrefix: 0xa7, "6", "R"), 22 | Bitcoin(name: "42coin", publicKeyPrefix: 0x08, privateKeyPrefix: 0x88, "5", "M"), 23 | Bitcoin(name: "Acoin", publicKeyPrefix: 0x17, privateKeyPrefix: 0xe6, "8", "b"), 24 | Bitcoin(name: "Alphacoin", publicKeyPrefix: 0x52, privateKeyPrefix: 0xd2, "8", "Y"), 25 | Bitcoin(name: "Animecoin", publicKeyPrefix: 0x17, privateKeyPrefix: 0x97, "6", "P"), 26 | Bitcoin(name: "Anoncoin", publicKeyPrefix: 0x17, privateKeyPrefix: 0x97, "6", "P"), 27 | Bitcoin(name: "Apexcoin", publicKeyPrefix: 0x17, privateKeyPrefix: 0x97, "6", "P"), 28 | Bitcoin(name: "Auroracoin", publicKeyPrefix: 0x17, privateKeyPrefix: 0x97, "6", "T"), 29 | Bitcoin(name: "Aquariuscoin", publicKeyPrefix: 0x17, privateKeyPrefix: 0x97, "6", "P"), 30 | Bitcoin(name: "BBQcoin", publicKeyPrefix: 0x55, privateKeyPrefix: 0xd5, "6", "T"), 31 | Bitcoin(name: "Biblepay", publicKeyPrefix: 0x19, privateKeyPrefix: 0xb6, "7", "[TU]"), 32 | Bitcoin(name: "BitcoinCash", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 33 | Bitcoin(name: "BitcoinDark", publicKeyPrefix: 0x3c, privateKeyPrefix: 0xbc, "7", "U"), 34 | Bitcoin(name: "BitcoinGold", publicKeyPrefix: 0x26, privateKeyPrefix: 0x80, "5", "[LK]"), 35 | Bitcoin(name: "Birdcoin", publicKeyPrefix: 0x2f, privateKeyPrefix: 0xaf, "6", "[ST]"), 36 | Bitcoin(name: "BitSynq", publicKeyPrefix: 0x3f, privateKeyPrefix: 0xbf, "7", "V"), 37 | Bitcoin(name: "Blackcoin", publicKeyPrefix: 0x19, privateKeyPrefix: 0x99, "6", "P"), 38 | Bitcoin(name: "BlackJack", publicKeyPrefix: 0x15, privateKeyPrefix: 0x95, "[56]", "P"), 39 | Bitcoin(name: "BolivarCoin", publicKeyPrefix: 0x55, privateKeyPrefix: 0xd5, "8", "Y"), 40 | Bitcoin(name: "BunnyCoin", publicKeyPrefix: 0x1a, privateKeyPrefix: 0x9a, "6", "P"), 41 | Bitcoin(name: "Cagecoin", publicKeyPrefix: 0x1f, privateKeyPrefix: 0x9f, "6", "Q"), 42 | Bitcoin(name: "CanadaeCoin", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x9c, "6", "Q"), 43 | Bitcoin(name: "CannabisCoin", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x9c, "6", "Q"), 44 | Bitcoin(name: "Capricoin", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x9c, "6", "Q"), 45 | Bitcoin(name: "CassubianDetk", publicKeyPrefix: 0x1e, privateKeyPrefix: 0x9e, "6", "Q"), 46 | Bitcoin(name: "CashCoin", publicKeyPrefix: 0x22, privateKeyPrefix: 0xa2, "6", "[QR]"), 47 | Bitcoin(name: "Catcoin", publicKeyPrefix: 0x15, privateKeyPrefix: 0x95, "[56]", "P"), 48 | Bitcoin(name: "ChainCoin", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x9c, "6", "Q"), 49 | Bitcoin(name: "ColossusCoinXT", publicKeyPrefix: 0x1e, privateKeyPrefix: 0xd4, "5", "[LK]"), 50 | Bitcoin(name: "Condensate", publicKeyPrefix: 0x3c, privateKeyPrefix: 0xbc, "7", "U"), 51 | Bitcoin(name: "Corgicoin", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x9c, "6", "Q"), 52 | Bitcoin(name: "CryptoBullion", publicKeyPrefix: 0xb, privateKeyPrefix: 0x8b, "5", "M"), 53 | Bitcoin(name: "CryptoClub", publicKeyPrefix: 0x23, privateKeyPrefix: 0xa3, "6", "R"), 54 | Bitcoin(name: "Cryptoescudo", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x9c, "6", "Q"), 55 | Bitcoin(name: "Cryptonite", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x80, "5", "[LK]"), 56 | Bitcoin(name: "CryptoWisdomCoin", publicKeyPrefix: 0x49, privateKeyPrefix: 0x87, "5", "[LM]"), 57 | Bitcoin(name: "C2coin", publicKeyPrefix: 0x1c, privateKeyPrefix: 0x9c, "6", "Q"), 58 | Bitcoin(name: "DeafDollars", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 59 | Bitcoin(name: "DeepOnion", publicKeyPrefix: 0x1f, privateKeyPrefix: 0x9f, "6", "Q"), 60 | Bitcoin(name: "Deutsche eMark", publicKeyPrefix: 0x35, privateKeyPrefix: 0xb5, "7", "T"), 61 | Bitcoin(name: "Devcoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 62 | Bitcoin(name: "DigiByte", publicKeyPrefix: 0x1e, privateKeyPrefix: 0x9e, "6", "Q"), 63 | Bitcoin(name: "Digitalcoin", publicKeyPrefix: 0x1e, privateKeyPrefix: 0x9e, "6", "Q"), 64 | Bitcoin(name: "Dogecoin", publicKeyPrefix: 0x1e, privateKeyPrefix: 0x9e, "6", "Q"), 65 | Bitcoin(name: "DogecoinDark", publicKeyPrefix: 0x1e, privateKeyPrefix: 0x9e, "6", "Q"), 66 | Bitcoin(name: "eGulden", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 67 | Bitcoin(name: "eKrona", publicKeyPrefix: 0x2d, privateKeyPrefix: 0xad, "6", "S"), 68 | Bitcoin(name: "ELECTRA", publicKeyPrefix: 0x21, privateKeyPrefix: 0xa1, "6", "Q"), 69 | Bitcoin(name: "Emerald", publicKeyPrefix: 0x22, privateKeyPrefix: 0xa2, "6", "[QR]"), 70 | Bitcoin(name: "Emercoin", publicKeyPrefix: 0x21, privateKeyPrefix: 0x80, "5", "[LK]"), 71 | Bitcoin(name: "EnergyCoin", publicKeyPrefix: 0x5c, privateKeyPrefix: 0xdc, "8", "Z"), 72 | Bitcoin(name: "Espers", publicKeyPrefix: 0x21, privateKeyPrefix: 0xa1, "6", "Q"), 73 | Bitcoin(name: "Fastcoin", publicKeyPrefix: 0x60, privateKeyPrefix: 0xe0, "8", "a"), 74 | Bitcoin(name: "Feathercoin", publicKeyPrefix: 0x0e, privateKeyPrefix: 0x8e, "5", "N"), 75 | Bitcoin(name: "Fedoracoin", publicKeyPrefix: 0x21, privateKeyPrefix: 0x80, "5", "[KL]"), 76 | Bitcoin(name: "Fibre", publicKeyPrefix: 0x23, privateKeyPrefix: 0xa3, "6", "R"), 77 | Bitcoin(name: "Florincoin", publicKeyPrefix: 0x23, privateKeyPrefix: 0xb0, "6", "T"), 78 | Bitcoin(name: "Flurbo", publicKeyPrefix: 0x23, privateKeyPrefix: 0x30, "6", "8"), 79 | Bitcoin(name: "Fluttercoin", publicKeyPrefix: 0x23, privateKeyPrefix: 0xa3, "6", "R"), 80 | Bitcoin(name: "FrazCoin", publicKeyPrefix: 0x23, privateKeyPrefix: 0xA3, "6", "R"), 81 | Bitcoin(name: "Freicoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 82 | Bitcoin(name: "FUDcoin", publicKeyPrefix: 0x23, privateKeyPrefix: 0xa3, "6", "R"), 83 | Bitcoin(name: "Fuelcoin", publicKeyPrefix: 0x24, privateKeyPrefix: 0x80, "5", "[KL]"), 84 | Bitcoin(name: "Fujicoin", publicKeyPrefix: 0x24, privateKeyPrefix: 0xa4, "6", "R"), 85 | Bitcoin(name: "GabenCoin", publicKeyPrefix: 0x10, privateKeyPrefix: 0x90, "5", "N"), 86 | Bitcoin(name: "GlobalBoost", publicKeyPrefix: 0x26, privateKeyPrefix: 0xa6, "6", "R"), 87 | Bitcoin(name: "Goodcoin", publicKeyPrefix: 0x26, privateKeyPrefix: 0xa6, "6", "R"), 88 | Bitcoin(name: "GridcoinResearch", publicKeyPrefix: 0x3e, privateKeyPrefix: 0xbe, "7", "V"), 89 | Bitcoin(name: "Gulden", publicKeyPrefix: 0x26, privateKeyPrefix: 0xa6, "6", "R"), 90 | Bitcoin(name: "Guncoin", publicKeyPrefix: 0x27, privateKeyPrefix: 0xa7, "6", "R"), 91 | Bitcoin(name: "HamRadioCoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "LK"), 92 | Bitcoin(name: "HOdlcoin", publicKeyPrefix: 0x28, privateKeyPrefix: 0xa8, "5", "[LK]"), 93 | Bitcoin(name: "HTML5Coin", publicKeyPrefix: 0x28, privateKeyPrefix: 0xa8, "6", "R"), 94 | Bitcoin(name: "HyperStake", publicKeyPrefix: 0x75, privateKeyPrefix: 0xf5, "9", "d"), 95 | Bitcoin(name: "ImperiumCoin", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 96 | Bitcoin(name: "IncaKoin", publicKeyPrefix: 0x35, privateKeyPrefix: 0xb5, "7", "T"), 97 | Bitcoin(name: "IncognitoCoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "LK"), 98 | Bitcoin(name: "Influxcoin", publicKeyPrefix: 0x66, privateKeyPrefix: 0xe6, "8", "b"), 99 | Bitcoin(name: "Innox", publicKeyPrefix: 0x4b, privateKeyPrefix: 0xcb, "7", "X"), 100 | Bitcoin(name: "IridiumCoin", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 101 | Bitcoin(name: "iCash", publicKeyPrefix: 0x66, privateKeyPrefix: 0xcc, "7", "X"), 102 | Bitcoin(name: "iXcoin", publicKeyPrefix: 0x8a, privateKeyPrefix: 0x80, "5", "[LK]"), 103 | Bitcoin(name: "Judgecoin", publicKeyPrefix: 0x2b, privateKeyPrefix: 0xab, "6", "S"), 104 | Bitcoin(name: "Jumbucks", publicKeyPrefix: 0x2b, privateKeyPrefix: 0xab, "6", "S"), 105 | Bitcoin(name: "Lanacoin", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 106 | Bitcoin(name: "Latium", publicKeyPrefix: 0x17, privateKeyPrefix: 0x80, "5", "[LK]"), 107 | Bitcoin(name: "LiteDoge", publicKeyPrefix: 0x5a, privateKeyPrefix: 0xab, "6", "S"), 108 | Bitcoin(name: "LoMoCoin", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 109 | Bitcoin(name: "MadbyteCoin", publicKeyPrefix: 0x32, privateKeyPrefix: 0x6e, "4", "H"), 110 | Bitcoin(name: "MagicInternetMoney", publicKeyPrefix: 0x30, privateKeyPrefix: 0xb0, "6", "T"), 111 | Bitcoin(name: "Magicoin", publicKeyPrefix: 0x14, privateKeyPrefix: 0x94, "5", "[NP]"), 112 | Bitcoin(name: "Marscoin", publicKeyPrefix: 0x32, privateKeyPrefix: 0xb2, "6", "T"), 113 | Bitcoin(name: "MarteXcoin", publicKeyPrefix: 0x32, privateKeyPrefix: 0xb2, "6", "T"), 114 | Bitcoin(name: "MasterDoge", publicKeyPrefix: 0x33, privateKeyPrefix: 0x8b, "5", "M"), 115 | Bitcoin(name: "Mazacoin", publicKeyPrefix: 0x32, privateKeyPrefix: 0xe0, "8", "a"), 116 | Bitcoin(name: "Megacoin", publicKeyPrefix: 0x32, privateKeyPrefix: 0xb2, "6", "T"), 117 | Bitcoin(name: "MintCoin", publicKeyPrefix: 0x33, privateKeyPrefix: 0xb3, "[67]", "T"), 118 | Bitcoin(name: "MobiusCoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 119 | Bitcoin(name: "MonetaryUnit", publicKeyPrefix: 0x10, privateKeyPrefix: 0x7e, "5", "K"), 120 | Bitcoin(name: "Monocle", publicKeyPrefix: 0x32, privateKeyPrefix: 0xb2, "6", "T"), 121 | Bitcoin(name: "MoonCoin", publicKeyPrefix: 0x03, privateKeyPrefix: 0x83, "5", "L"), 122 | Bitcoin(name: "Myriadcoin", publicKeyPrefix: 0x32, privateKeyPrefix: 0xb2, "6", "T"), 123 | Bitcoin(name: "NameCoin", publicKeyPrefix: 0x34, privateKeyPrefix: 0x80, "5", "[LK]"), 124 | Bitcoin(name: "Navcoin", publicKeyPrefix: 0x35, privateKeyPrefix: 0x96, "6", "P"), 125 | Bitcoin(name: "NeedleCoin", publicKeyPrefix: 0x35, privateKeyPrefix: 0xb5, "7", "T"), 126 | Bitcoin(name: "Neoscoin", publicKeyPrefix: 0x35, privateKeyPrefix: 0xb1, "6", "T"), 127 | Bitcoin(name: "Nevacoin", publicKeyPrefix: 0x35, privateKeyPrefix: 0xb1, "6", "T"), 128 | Bitcoin(name: "Novacoin", publicKeyPrefix: 0x08, privateKeyPrefix: 0x88, "5", "M"), 129 | Bitcoin(name: "Nubits", publicKeyPrefix: 0x19, privateKeyPrefix: 0xbf, "7", "V"), 130 | Bitcoin(name: "Ocupy", publicKeyPrefix: 0x73, privateKeyPrefix: 0xf3, "9", "[cd]"), 131 | Bitcoin(name: "Omnicoin", publicKeyPrefix: 0x73, privateKeyPrefix: 0xf3, "9", "[cd]"), 132 | Bitcoin(name: "Onyxcoin", publicKeyPrefix: 0x73, privateKeyPrefix: 0xf3, "9", "[cd]"), 133 | Bitcoin(name: "Particl", publicKeyPrefix: 0x38, privateKeyPrefix: 0x6c, "4", "[HG]"), 134 | Bitcoin(name: "Paycoin", publicKeyPrefix: 0x37, privateKeyPrefix: 0xb7, "7", "U"), 135 | Bitcoin(name: "Pandacoin", publicKeyPrefix: 0x37, privateKeyPrefix: 0xb7, "7", "U"), 136 | Bitcoin(name: "ParkByte", publicKeyPrefix: 0x37, privateKeyPrefix: 0xb7, "7", "U"), 137 | Bitcoin(name: "Pesetacoin", publicKeyPrefix: 0x2f, privateKeyPrefix: 0xaf, "6", "[ST]"), 138 | Bitcoin(name: "PHCoin", publicKeyPrefix: 0x37, privateKeyPrefix: 0xb7, "7", "U"), 139 | Bitcoin(name: "PhoenixCoin", publicKeyPrefix: 0x38, privateKeyPrefix: 0xb8, "7", "U"), 140 | Bitcoin(name: "Pinkcoin", publicKeyPrefix: 0x3, privateKeyPrefix: 0x83, "[RQP]","L"), 141 | Bitcoin(name: "PIVX", publicKeyPrefix: 0x1e, privateKeyPrefix: 0xd4, "8", "Y"), 142 | Bitcoin(name: "Peercoin", publicKeyPrefix: 0x37, privateKeyPrefix: 0xb7, "7", "U"), 143 | Bitcoin(name: "Potcoin", publicKeyPrefix: 0x37, privateKeyPrefix: 0xb7, "7", "U"), 144 | Bitcoin(name: "Primecoin", publicKeyPrefix: 0x17, privateKeyPrefix: 0x97, "6", "P"), 145 | Bitcoin(name: "ProsperCoinClassic", publicKeyPrefix: 0x3a, privateKeyPrefix: 0xba, "7", "Q"), 146 | Bitcoin(name: "Quark", publicKeyPrefix: 0x3a, privateKeyPrefix: 0xba, "7", "U"), 147 | Bitcoin(name: "Qubitcoin", publicKeyPrefix: 0x26, privateKeyPrefix: 0xe0, "8", "a"), 148 | Bitcoin(name: "Reddcoin", publicKeyPrefix: 0x3d, privateKeyPrefix: 0xbd, "7", "[UV]"), 149 | Bitcoin(name: "Riecoin", publicKeyPrefix: 0x3c, privateKeyPrefix: 0x80, "5", "[LK]"), 150 | Bitcoin(name: "Rimbit", publicKeyPrefix: 0x3c, privateKeyPrefix: 0xbc, "7", "U"), 151 | Bitcoin(name: "ROIcoin", publicKeyPrefix: 0x3c, privateKeyPrefix: 0x80, "5", "[LK]"), 152 | Bitcoin(name: "Rubycoin", publicKeyPrefix: 0x3c, privateKeyPrefix: 0xbc, "7", "U"), 153 | Bitcoin(name: "Rupaya", publicKeyPrefix: 0x3c, privateKeyPrefix: 0xbc, "7", "U"), 154 | Bitcoin(name: "Sambacoin", publicKeyPrefix: 0x3e, privateKeyPrefix: 0xbe, "7", "V"), 155 | Bitcoin(name: "SecKCoin", publicKeyPrefix: 0x3f, privateKeyPrefix: 0xbf, "7", "V"), 156 | Bitcoin(name: "SibCoin", publicKeyPrefix: 0x3f, privateKeyPrefix: 0x80, "5", "[LK]"), 157 | Bitcoin(name: "SixEleven", publicKeyPrefix: 0x34, privateKeyPrefix: 0x80, "5", "[LK]"), 158 | Bitcoin(name: "SmileyCoin", publicKeyPrefix: 0x19, privateKeyPrefix: 0x99, "6", "P"), 159 | Bitcoin(name: "SongCoin", publicKeyPrefix: 0x3f, privateKeyPrefix: 0xbf, "7", "V"), 160 | Bitcoin(name: "SpreadCoin", publicKeyPrefix: 0x3f, privateKeyPrefix: 0xbf, "7", "V"), 161 | Bitcoin(name: "StealthCoin", publicKeyPrefix: 0x3e, privateKeyPrefix: 0xbe, "7", "V"), 162 | Bitcoin(name: "Stratis", publicKeyPrefix: 0x3f, privateKeyPrefix: 0xbf, "7", "V"), 163 | Bitcoin(name: "SwagBucks", publicKeyPrefix: 0x3f, privateKeyPrefix: 0x99, "6", "P"), 164 | Bitcoin(name: "Syscoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 165 | Bitcoin(name: "Tajcoin", publicKeyPrefix: 0x41, privateKeyPrefix: 0x6f, "6", "H"), 166 | Bitcoin(name: "Terracoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 167 | Bitcoin(name: "Titcoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 168 | Bitcoin(name: "TittieCoin", publicKeyPrefix: 0x41, privateKeyPrefix: 0xc1, "7", "V"), 169 | Bitcoin(name: "Topcoin", publicKeyPrefix: 0x42, privateKeyPrefix: 0xc2, "7", "V"), 170 | Bitcoin(name: "TransferCoin", publicKeyPrefix: 0x42, privateKeyPrefix: 0x99, "6", "P"), 171 | Bitcoin(name: "TreasureHuntCoin", publicKeyPrefix: 0x32, privateKeyPrefix: 0xb2, "6", "T"), 172 | Bitcoin(name: "TrezarCoin", publicKeyPrefix: 0x42, privateKeyPrefix: 0xC2, "9", "V"), 173 | Bitcoin(name: "Unobtanium", publicKeyPrefix: 0x82, privateKeyPrefix: 0xe0, "8", "a"), 174 | Bitcoin(name: "USDe", publicKeyPrefix: 0x26, privateKeyPrefix: 0xa6, "6", "R"), 175 | Bitcoin(name: "Vcash", publicKeyPrefix: 0x47, privateKeyPrefix: 0xc7, "7", "W"), 176 | Bitcoin(name: "Versioncoin", publicKeyPrefix: 0x46, privateKeyPrefix: 0xc6, "7", "W"), 177 | Bitcoin(name: "Vertcoin", publicKeyPrefix: 0x47, privateKeyPrefix: 0xc7, "7", "W"), 178 | Bitcoin(name: "Viacoin", publicKeyPrefix: 0x47, privateKeyPrefix: 0xc7, "7", "W"), 179 | Bitcoin(name: "VikingCoin", publicKeyPrefix: 0x46, privateKeyPrefix: 0x56, "3", "D"), 180 | Bitcoin(name: "W2Coin", publicKeyPrefix: 0x49, privateKeyPrefix: 0xc9, "7", "W"), 181 | Bitcoin(name: "WACoins", publicKeyPrefix: 0x49, privateKeyPrefix: 0xc9, "7", "W"), 182 | Bitcoin(name: "WankCoin", publicKeyPrefix: 0x00, privateKeyPrefix: 0x80, "5", "[LK]"), 183 | Bitcoin(name: "WeAreSatoshiCoin", publicKeyPrefix: 0x87, privateKeyPrefix: 0x97, "6", "P"), 184 | Bitcoin(name: "WorldCoin", publicKeyPrefix: 0x49, privateKeyPrefix: 0xc9, "7", "W"), 185 | Bitcoin(name: "XP", publicKeyPrefix: 0x4b, privateKeyPrefix: 0xcb, "7", "X"), 186 | Bitcoin(name: "Zetacoin", publicKeyPrefix: 0x50, privateKeyPrefix: 0xE0, "8", "a"), 187 | Bitcoin(name: "Testnet Bitcoin", publicKeyPrefix: 0x6f, privateKeyPrefix: 0xef, "9", "c"), 188 | Bitcoin(name: "Testnet Dogecoin", publicKeyPrefix: 0x71, privateKeyPrefix: 0xf1, "9", "c"), 189 | Bitcoin(name: "Testnet MonetaryUnit", publicKeyPrefix: 0x26, privateKeyPrefix: 0x40, "3", "A"), 190 | Bitcoin(name: "Testnet PIVX", publicKeyPrefix: 0x8b, privateKeyPrefix: 0xef, "9", "c"), 191 | Bitcoin(name: "Testnet WACoins", publicKeyPrefix: 0x51, privateKeyPrefix: 0xd1, "8", "[XY]") 192 | ] 193 | } 194 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/EthereumGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// Used for Ethereum and similar coins 11 | struct EthereumGenerator { 12 | func generate(publicKey: Data) throws -> String { 13 | return try publicKey 14 | .dropFirstByte() 15 | .keccak256() 16 | .takeLast(byteCount: 20) 17 | .hexDump() 18 | .toString() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/InternalError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | enum InteralError: Error { 11 | case invalid 12 | } 13 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/KeyPairGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// Generate public key - private key pair 11 | final class KeyPairGenerator { 12 | 13 | /// Binary key only in DER format 14 | struct KeyPair { 15 | let publicKey: Data 16 | let privateKey: Data 17 | } 18 | 19 | func generate() throws -> KeyPair { 20 | // https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses 21 | 22 | // 0 - Having a private ECDSA key 23 | let pem = try Task.run(command: "openssl ecparam -name secp256k1 -genkey -noout") 24 | 25 | let privateKey = try Task.run( 26 | command: "openssl ec -outform DER | tail -c +8 | head -c 32", 27 | input: pem 28 | ) 29 | 30 | // 1 - Take the corresponding public key generated with it 31 | let publicKey = try Task.run( 32 | command: "openssl ec -pubout -outform DER | tail -c 65", 33 | input: pem 34 | ) 35 | 36 | return KeyPair( 37 | publicKey: publicKey, 38 | privateKey: privateKey 39 | ) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/Manager.swift: -------------------------------------------------------------------------------- 1 | import Foundation 2 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/MoneroGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MoneroGenerator.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 07.01.2018. 6 | // Copyright © 2018 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // https://getmonero.org/resources/moneropedia/address.html 12 | struct MoneroGenerator { 13 | func generate() throws -> Data { 14 | fatalError() 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/Pay2PubKeyHashGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import AppKit 9 | 10 | // https://en.bitcoin.it/wiki/Address 11 | // https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash 12 | // Common P2PKH which begin with the number 1 13 | // https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses 14 | struct Pay2PubKeyHashGenerator { 15 | func generate(publicKey: Data, prefix: UInt8) throws -> String { 16 | let extendedRmd160Hash = try publicKey 17 | // 2 - Perform SHA-256 hashing on the public key 18 | .sha256() 19 | // 3 - Perform RIPEMD-160 hashing on the result of SHA-256 20 | .rmd160() 21 | // 4 - Add version byte in front of RIPEMD-160 hash (0x00 for Main Network) 22 | .prepend(number: prefix) 23 | 24 | let checksum = try extendedRmd160Hash 25 | // 5 - Perform SHA-256 hash on the extended RIPEMD-160 result 26 | .sha256() 27 | // 6 - Perform SHA-256 hash on the result of the previous SHA-256 hash 28 | .sha256() 29 | // 7 - Take the first 4 bytes of the second SHA-256 hash. This is the address checksum 30 | .takeFirst(byteCount: 4) 31 | 32 | // 8 - Add the 4 checksum bytes from stage 7 at the end of extended RIPEMD-160 hash from stage 4. 33 | // This is the 25-byte binary Bitcoin Address. 34 | let address = extendedRmd160Hash.append(data: checksum) 35 | 36 | return address.base58EncodedString() 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/Pay2ScriptHashGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import AppKit 9 | 10 | // https://en.bitcoin.it/wiki/Address 11 | // https://en.bitcoin.it/wiki/Pay_to_script_hash 12 | // Newer P2SH type starting with the number 3 13 | struct Pay2ScriptHashGenerator { 14 | func generate() throws -> String { 15 | fatalError() 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/PublicKeyCompressor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PublicKeyCompressor.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 06.01.2018. 6 | // Copyright © 2018 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // http://davidederosa.com/basic-blockchain-programming/elliptic-curve-keys/ 12 | struct PublicKeyCompressor { 13 | func compress(publicKey: Data) -> Data { 14 | var x = publicKey.takeFirst(byteCount: 1 + 32) 15 | let postfix = publicKey[64] 16 | let prefix: UInt8 = (postfix % 2 == 0) ? 0x02 : 0x03 17 | x[0] = prefix 18 | return x 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/RippleGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RippleGenerator.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 06.01.2018. 6 | // Copyright © 2018 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // https://ripple.com/build/accounts/ 12 | struct RippleGenerator { 13 | func generate(publicKey: Data) throws -> String { 14 | let accountId = 15 | // Start with a 33-byte ECDSA secp256k1 public key 16 | try PublicKeyCompressor().compress(publicKey: publicKey) 17 | // Calculate the RIPEMD160 hash of the SHA-256 hash of the public key. 18 | // This value is the "Account ID" 19 | .sha256() 20 | .rmd160() 21 | 22 | let payload = accountId 23 | // "r" in Ripple base58 24 | .prepend(number: 0x00) 25 | 26 | // Calculate the SHA-256 hash of the SHA-256 hash of the Account ID; 27 | // take the first 4 bytes. This value is the "checksum". 28 | let checksum = try payload 29 | .sha256() 30 | .sha256() 31 | .takeFirst(byteCount: 4) 32 | 33 | // Concatenate the payload and the checksum. Calculate the base58 value of the concatenated buffer. The result is the address. 34 | let address = payload.append(data: checksum) 35 | 36 | return address.base58EncodedString(alphabet: Base58Alphabet.ripple.rawValue) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/SwiftBaseX.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseX.swift 3 | // SwiftBaseX 4 | // 5 | // Created by Pelle Steffen Braendgaard on 7/22/17. 6 | // Copyright © 2017 Consensys AG. All rights reserved. 7 | // 8 | 9 | // https://raw.githubusercontent.com/uport-project/SwiftBaseX/develop/SwiftBaseX/BaseX.swift 10 | 11 | import Foundation 12 | 13 | enum Base58Alphabet: String { 14 | case normal = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" 15 | 16 | // R_B58_DICT from https://ripple.com/build/accounts/ 17 | case ripple = "rpshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqi1tuvAxyz" 18 | } 19 | 20 | private func buildAlphabetBase(_ alphabet: String) -> (map: [Character:UInt], indexed: [Character], base: UInt, leader: Character) { 21 | let characters = alphabet 22 | let indexed:[Character] = characters.map {$0} 23 | var tmpMap = [Character: UInt]() 24 | var i:UInt = 0 25 | for c in characters { 26 | tmpMap[c] = i 27 | i += 1 28 | } 29 | 30 | let finalMap = tmpMap 31 | return (map: finalMap, indexed: indexed, base: UInt(characters.count), leader: characters.first!) 32 | } 33 | 34 | private func encodeData(alpha: (map:[Character:UInt], indexed:[Character], base: UInt, leader: Character), data: Data) -> String { 35 | if data.count == 0 { 36 | return "" 37 | } 38 | let bytes = [UInt8](data) 39 | 40 | var digits:[UInt] = [0] 41 | for byte in bytes { 42 | var carry = UInt(byte) 43 | for j in 0.. 0) { 49 | digits.append(carry % alpha.base) 50 | carry = (carry / alpha.base) | 0 51 | } 52 | } 53 | 54 | var output: String = "" 55 | // deal with leading zeros 56 | for k in 0.. String { 74 | return encodeData( 75 | alpha: buildAlphabetBase(alphabet), 76 | data: self 77 | ) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/Task.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import AppKit 9 | 10 | final class Task { 11 | 12 | static func run(command: String, input: Data? = nil) throws -> Data { 13 | let process = Process() 14 | process.launchPath = "/bin/bash" 15 | process.arguments = ["-c", command] 16 | 17 | // output 18 | let outputPipe = Pipe() 19 | var outputData = Data() 20 | process.standardOutput = outputPipe 21 | 22 | outputPipe.fileHandleForReading.readabilityHandler = { handler in 23 | let data = handler.availableData 24 | outputData.append(data) 25 | } 26 | 27 | // input 28 | if let data = input { 29 | let inputPipe = Pipe() 30 | let handle = inputPipe.fileHandleForWriting 31 | handle.write(data) 32 | handle.closeFile() 33 | 34 | process.standardInput = inputPipe 35 | } 36 | 37 | // launch 38 | process.launch() 39 | process.waitUntilExit() 40 | 41 | // clean 42 | outputPipe.fileHandleForReading.readabilityHandler = nil 43 | 44 | return outputData 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Engine/WalletImportFormatGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | // https://en.bitcoin.it/wiki/Wallet_import_format 11 | class WalletImportFormatGenerator { 12 | 13 | func generate(privateKey: Data, prefix: UInt8) throws -> String { 14 | let extendedKey = privateKey 15 | .prepend(number: prefix) 16 | 17 | let checksum = try extendedKey 18 | .sha256() 19 | .sha256() 20 | .takeFirst(byteCount: 4) 21 | 22 | return extendedKey 23 | .append(data: checksum) 24 | .base58EncodedString() 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Extensions/Data+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Data { 11 | func toString() -> String { 12 | guard let string = String(data: self, encoding: .utf8) else { 13 | return "" 14 | } 15 | 16 | if string.hasSuffix("\n") { 17 | let endIndex = string.index(before: string.endIndex) 18 | return String(string[.. Data { 25 | return try Task.run(command: command, input: self) 26 | } 27 | 28 | func hexDump() throws -> Data { 29 | return try Task.run(command: "xxd -p -c \(count)", input: self) 30 | } 31 | 32 | func prepend(number: UInt8) -> Data { 33 | var number = number 34 | var data = Data(bytes: &number, count: MemoryLayout.size(ofValue: number)) 35 | data.append(self) 36 | 37 | return data 38 | } 39 | 40 | func append(data: Data) -> Data { 41 | var currentData = self 42 | currentData.append(data) 43 | return currentData 44 | } 45 | 46 | func takeFirst(byteCount: UInt) -> Data { 47 | return self[0.. Data { 51 | return Data(dropFirst()) 52 | } 53 | 54 | func takeLast(byteCount: Int) -> Data { 55 | return subdata(in: count-byteCount.. Data { 59 | let len = hexString.count / 2 60 | var data = Data(capacity: len) 61 | for i in 0.. Data { 78 | return try Task.run(command: "openssl dgst -sha256 -binary", input: self) 79 | } 80 | 81 | func rmd160() throws -> Data { 82 | return try Task.run(command: "openssl dgst -rmd160 -binary", input: self) 83 | } 84 | 85 | func keccak256() throws -> Data { 86 | return try KeccakHash().hash(data: self) 87 | } 88 | } 89 | 90 | extension Data { 91 | func toPointer() -> UnsafePointer? { 92 | let buffer = UnsafeMutablePointer.allocate(capacity: count) 93 | let stream = OutputStream(toBuffer: buffer, capacity: count) 94 | 95 | stream.open() 96 | withUnsafeBytes({ (p: UnsafePointer) -> Void in 97 | stream.write(p, maxLength: count) 98 | }) 99 | 100 | stream.close() 101 | 102 | return UnsafePointer(buffer) 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Extensions/String+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | extension String { 11 | func toData() throws -> Data { 12 | guard let data = data(using: .utf8) else { 13 | throw InteralError.invalid 14 | } 15 | 16 | return data 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Extensions/UnsafePointer+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | extension UnsafeMutablePointer { 11 | func toData() -> Data { 12 | return Data(bytes: UnsafeRawPointer(self), count: 32) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Hash/keccak/KeccakHash.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import Foundation 9 | 10 | /// // https://github.com/ethereum/ethash/blob/master/src/libethash/sha3.c 11 | class KeccakHash { 12 | func hash(data: Data) throws -> Data { 13 | guard let dataPointer = data.toPointer() else { 14 | throw InteralError.invalid 15 | } 16 | 17 | let byteCount = 32 18 | 19 | let result = UnsafeMutablePointer.allocate(capacity: byteCount) 20 | sha3_256(result, byteCount, dataPointer, data.count) 21 | return result.toData() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Hash/keccak/sha3.c: -------------------------------------------------------------------------------- 1 | /** libkeccak-tiny 2 | * 3 | * A single-file implementation of SHA-3 and SHAKE. 4 | * 5 | * Implementor: David Leon Gil 6 | * License: CC0, attribution kindly requested. Blame taken too, 7 | * but not liability. 8 | */ 9 | #include "sha3.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /******** The Keccak-f[1600] permutation ********/ 17 | 18 | /*** Constants. ***/ 19 | static const uint8_t rho[24] = \ 20 | { 1, 3, 6, 10, 15, 21, 21 | 28, 36, 45, 55, 2, 14, 22 | 27, 41, 56, 8, 25, 43, 23 | 62, 18, 39, 61, 20, 44}; 24 | static const uint8_t pi[24] = \ 25 | {10, 7, 11, 17, 18, 3, 26 | 5, 16, 8, 21, 24, 4, 27 | 15, 23, 19, 13, 12, 2, 28 | 20, 14, 22, 9, 6, 1}; 29 | static const uint64_t RC[24] = \ 30 | {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL, 31 | 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL, 32 | 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL, 33 | 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL, 34 | 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL, 35 | 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL}; 36 | 37 | /*** Helper macros to unroll the permutation. ***/ 38 | #define rol(x, s) (((x) << s) | ((x) >> (64 - s))) 39 | #define REPEAT6(e) e e e e e e 40 | #define REPEAT24(e) REPEAT6(e e e e) 41 | #define REPEAT5(e) e e e e e 42 | #define FOR5(v, s, e) \ 43 | v = 0; \ 44 | REPEAT5(e; v += s;) 45 | 46 | /*** Keccak-f[1600] ***/ 47 | static inline void keccakf(void* state) { 48 | uint64_t* a = (uint64_t*)state; 49 | uint64_t b[5] = {0}; 50 | uint64_t t = 0; 51 | uint8_t x, y; 52 | 53 | for (int i = 0; i < 24; i++) { 54 | // Theta 55 | FOR5(x, 1, 56 | b[x] = 0; 57 | FOR5(y, 5, 58 | b[x] ^= a[x + y]; )) 59 | FOR5(x, 1, 60 | FOR5(y, 5, 61 | a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); )) 62 | // Rho and pi 63 | t = a[1]; 64 | x = 0; 65 | REPEAT24(b[0] = a[pi[x]]; 66 | a[pi[x]] = rol(t, rho[x]); 67 | t = b[0]; 68 | x++; ) 69 | // Chi 70 | FOR5(y, 71 | 5, 72 | FOR5(x, 1, 73 | b[x] = a[y + x];) 74 | FOR5(x, 1, 75 | a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); )) 76 | // Iota 77 | a[0] ^= RC[i]; 78 | } 79 | } 80 | 81 | /******** The FIPS202-defined functions. ********/ 82 | 83 | /*** Some helper macros. ***/ 84 | 85 | #define _(S) do { S } while (0) 86 | #define FOR(i, ST, L, S) \ 87 | _(for (size_t i = 0; i < L; i += ST) { S; }) 88 | #define mkapply_ds(NAME, S) \ 89 | static inline void NAME(uint8_t* dst, \ 90 | const uint8_t* src, \ 91 | size_t len) { \ 92 | FOR(i, 1, len, S); \ 93 | } 94 | #define mkapply_sd(NAME, S) \ 95 | static inline void NAME(const uint8_t* src, \ 96 | uint8_t* dst, \ 97 | size_t len) { \ 98 | FOR(i, 1, len, S); \ 99 | } 100 | 101 | mkapply_ds(xorin, dst[i] ^= src[i]) // xorin 102 | mkapply_sd(setout, dst[i] = src[i]) // setout 103 | 104 | #define P keccakf 105 | #define Plen 200 106 | 107 | // Fold P*F over the full blocks of an input. 108 | #define foldP(I, L, F) \ 109 | while (L >= rate) { \ 110 | F(a, I, rate); \ 111 | P(a); \ 112 | I += rate; \ 113 | L -= rate; \ 114 | } 115 | 116 | /** The sponge-based hash construction. **/ 117 | static inline int hash(uint8_t* out, size_t outlen, 118 | const uint8_t* in, size_t inlen, 119 | size_t rate, uint8_t delim) { 120 | if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) { 121 | return -1; 122 | } 123 | uint8_t a[Plen] = {0}; 124 | // Absorb input. 125 | foldP(in, inlen, xorin); 126 | // Xor in the DS and pad frame. 127 | a[inlen] ^= delim; 128 | a[rate - 1] ^= 0x80; 129 | // Xor in the last block. 130 | xorin(a, in, inlen); 131 | // Apply P 132 | P(a); 133 | // Squeeze output. 134 | foldP(out, outlen, setout); 135 | setout(a, out, outlen); 136 | memset(a, 0, 200); 137 | return 0; 138 | } 139 | 140 | #define defsha3(bits) \ 141 | int sha3_##bits(uint8_t* out, size_t outlen, \ 142 | const uint8_t* in, size_t inlen) { \ 143 | if (outlen > (bits/8)) { \ 144 | return -1; \ 145 | } \ 146 | return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \ 147 | } 148 | 149 | /*** FIPS202 SHA3 FOFs ***/ 150 | defsha3(256) 151 | defsha3(512) 152 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Crypto/Hash/keccak/sha3.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include 8 | #include 9 | 10 | struct ethash_h256; 11 | 12 | #define decsha3(bits) \ 13 | int sha3_##bits(uint8_t*, size_t, uint8_t const*, size_t); 14 | 15 | decsha3(256) 16 | decsha3(512) 17 | 18 | static inline void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t const size) 19 | { 20 | sha3_256((uint8_t*)ret, 32, data, size); 21 | } 22 | 23 | static inline void SHA3_512(uint8_t* ret, uint8_t const* data, size_t const size) 24 | { 25 | sha3_512(ret, 64, data, size); 26 | } 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /AddressGenerator/Library/Utils/QRCodeGenerator.swift: -------------------------------------------------------------------------------- 1 | // 2 | // QRCodeGenerator.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 06.01.2018. 6 | // Copyright © 2018 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | 11 | final class QRCodeGenerator { 12 | func generate(string: String, size: CGSize) -> NSImage? { 13 | guard let data = string.data(using: .utf8) else { 14 | return nil 15 | } 16 | 17 | // Filter 18 | guard let filter = CIFilter(name: "CIQRCodeGenerator") else { 19 | return nil 20 | } 21 | 22 | filter.setValue(data, forKey: "inputMessage") 23 | filter.setValue("Q", forKey: "inputCorrectionLevel") 24 | 25 | // CIImage 26 | guard let ciImage = filter.outputImage else { 27 | return nil 28 | } 29 | 30 | // NSImage 31 | let rep = NSCIImageRep(ciImage: ciImage) 32 | let image = NSImage(size: rep.size) 33 | image.addRepresentation(rep) 34 | 35 | // Scale 36 | let finalImage = NSImage(size: size) 37 | finalImage.lockFocus() 38 | NSGraphicsContext.current?.imageInterpolation = .none 39 | image.draw(in: NSRect(origin: .zero, size: size)) 40 | finalImage.unlockFocus() 41 | 42 | return finalImage 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /AddressGenerator/Views/Cell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cell.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 21.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | import Anchors 11 | import Omnia 12 | 13 | final class Cell: NSCollectionViewItem { 14 | let label = Label() 15 | let coinImageView = NSImageView() 16 | 17 | override func loadView() { 18 | self.view = NSView() 19 | self.view.wantsLayer = true 20 | } 21 | 22 | override func viewDidLoad() { 23 | super.viewDidLoad() 24 | 25 | view.e_addSubviews([ 26 | coinImageView, label 27 | ]) 28 | 29 | view.wantsLayer = true 30 | view.layer?.cornerRadius = 2 31 | view.layer?.backgroundColor = NSColor(e_hex: "#1E1E1E").cgColor 32 | 33 | activate( 34 | coinImageView.anchor.top.left.constant(4), 35 | coinImageView.anchor.bottom.constant(-4), 36 | coinImageView.anchor.width.ratio(1), 37 | 38 | label.anchor.centerY.equal.to(coinImageView.anchor.centerY), 39 | label.anchor.left.equal.to(coinImageView.anchor.right).constant(10) 40 | ) 41 | } 42 | 43 | override var isSelected: Bool { 44 | didSet { 45 | if isSelected { 46 | view.layer?.borderWidth = 1 47 | view.layer?.borderColor = NSColor(e_hex: "FD4514").cgColor 48 | } else { 49 | view.layer?.borderWidth = 0 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /AddressGenerator/Views/Label.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Label.swift 3 | // AddressGenerator 4 | // 5 | // Created by Khoa Pham on 21.12.2017. 6 | // Copyright © 2017 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import AppKit 10 | 11 | final class Label: NSTextField { 12 | override init(frame frameRect: NSRect) { 13 | super.init(frame: frameRect) 14 | 15 | isEditable = false 16 | isBezeled = false 17 | drawsBackground = false 18 | textColor = .white 19 | } 20 | 21 | required init?(coder: NSCoder) { 22 | fatalError() 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /AddressGeneratorTests/AddressGeneratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class AddressGeneratorTests: XCTestCase { 12 | func testPay2PubKeyHashGenerator() { 13 | let publicKey = "041a12f855d14451b786716164b8325da324aeed3f840fe77257feadfae2f1b0786105ddc906b6bcafb84a9a142bba69e77ad2f21c877c11f0b29676cbdf767af2" 14 | let publicKeyData = try! Data.from(hexString: publicKey) 15 | let address = try! Pay2PubKeyHashGenerator().generate(publicKey: publicKeyData, prefix: 0x00) 16 | 17 | XCTAssertEqual(address.count, 34) 18 | XCTAssertEqual(address, "1KRA1Q6tTxHA3otFGpwnrBVxf5TBe97zWp") 19 | } 20 | 21 | func testWalletImportFormatGenerator() { 22 | let privateKey = "896462332ff505dccfd04a61eea9ece054e0a0873d3bd9d92ddd8a0f27c0c275" 23 | let privateKeyData = try! Data.from(hexString: privateKey) 24 | let wif = try! WalletImportFormatGenerator().generate(privateKey: privateKeyData, prefix: 0x80) 25 | 26 | XCTAssertEqual(wif.count, 51) 27 | XCTAssertEqual(wif, "5Jro5XgQ7PCSr3rk8FRvYVqmGtRUr4xj2qSexxvNPVwahEe9R5m") 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /AddressGeneratorTests/CoinListTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class CoinListTests: XCTestCase { 12 | /// Heavy test 13 | func _testWifStart() { 14 | let coins = CoinList.allCoins.flatMap({ $0 as? Bitcoin }) 15 | for coin in coins { 16 | do { 17 | let account = try coin.generate() 18 | XCTAssertTrue(account.walletImportFormat!.starts(with: coin.wifStart), coin.name) 19 | } catch { 20 | XCTFail(coin.name) 21 | } 22 | } 23 | } 24 | } 25 | 26 | 27 | -------------------------------------------------------------------------------- /AddressGeneratorTests/DataExtensionsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class DataExtensionsTests: XCTestCase { 12 | func testSha256() { 13 | do { 14 | let data = "hello".data(using: .utf8)! 15 | let hash = try! data.sha256() 16 | XCTAssertEqual(hash.count, 32) 17 | XCTAssertEqual(try! hash.hexDump().toString().count, 64) 18 | } 19 | 20 | do { 21 | let publicKey = "04d0988bfa799f7d7ef9ab3de97ef481cd0f75d2367ad456607647edde665d6f6fbdd594388756a7beaf73b4822bc22d36e9bda7db82df2b8b623673eefc0b7495" 22 | let data = publicKey.data(using: .utf8)! 23 | let hash = try data.sha256() 24 | XCTAssertEqual(hash.count, 32) 25 | XCTAssertEqual( 26 | try hash.hexDump().toString(), 27 | "52263faf869bbf7f0b52cbc54a835d3c8bbd6206ee4eec2e975c033c8016801f" 28 | ) 29 | } catch { 30 | XCTFail() 31 | } 32 | } 33 | 34 | func testRmd160() { 35 | do { 36 | let data = "hello".data(using: .utf8)! 37 | let hash = try! data.rmd160() 38 | XCTAssertEqual(hash.count, 20) 39 | XCTAssertEqual(try! hash.hexDump().toString().count, 40) 40 | } 41 | 42 | do { 43 | let sha256 = "52263faf869bbf7f0b52cbc54a835d3c8bbd6206ee4eec2e975c033c8016801f" 44 | let data = sha256.data(using: .utf8)! 45 | let hash = try data.rmd160() 46 | XCTAssertEqual(hash.count, 20) 47 | XCTAssertEqual( 48 | try hash.hexDump().toString(), 49 | "224e60c530f4b6ba1c629858a8d819c86b77d2f9" 50 | ) 51 | } catch { 52 | XCTFail() 53 | } 54 | } 55 | 56 | func testPrepend() { 57 | do { 58 | let rmd160 = "224e60c530f4b6ba1c629858a8d819c86b77d2f9" 59 | let data = try! Data.from(hexString: rmd160) 60 | let prepend = data.prepend(number: 0x00) 61 | XCTAssertEqual(prepend.count, 21) 62 | XCTAssertEqual( 63 | try prepend.hexDump().toString(), 64 | "00224e60c530f4b6ba1c629858a8d819c86b77d2f9" 65 | ) 66 | } 67 | } 68 | 69 | func testTakeFirst() { 70 | do { 71 | let extendedRmd160 = "00224e60c530f4b6ba1c629858a8d819c86b77d2f9" 72 | let data = try Data.from(hexString: extendedRmd160) 73 | let hash = try data.sha256().sha256() 74 | let take = hash.takeFirst(byteCount: 4) 75 | 76 | XCTAssertEqual(take.count, 4) 77 | XCTAssertEqual( 78 | try take.hexDump().toString(), 79 | "579db493" 80 | ) 81 | } catch { 82 | XCTFail() 83 | } 84 | } 85 | 86 | func testAppend() { 87 | do { 88 | let extendedRmd160 = "00224e60c530f4b6ba1c629858a8d819c86b77d2f9" 89 | let data = try! Data.from(hexString: extendedRmd160) 90 | let address = try! data.append(data: Data.from(hexString: "579db493")) 91 | 92 | XCTAssertEqual(address.count, 25) 93 | XCTAssertEqual( 94 | try address.hexDump().toString(), 95 | "00224e60c530f4b6ba1c629858a8d819c86b77d2f9579db493" 96 | ) 97 | } 98 | } 99 | 100 | func testTakeLast() { 101 | do { 102 | let hexString = "88c38cf02f615519608f7eee3f5b765f6a9007a7a08b07c04acd391441045c1d" 103 | let data = try! Data.from(hexString: hexString) 104 | let take = data.takeLast(byteCount: 20) 105 | 106 | XCTAssertEqual(take.count, 20) 107 | XCTAssertEqual( 108 | try take.hexDump().toString(), 109 | "3f5b765f6a9007a7a08b07c04acd391441045c1d" 110 | ) 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /AddressGeneratorTests/EthereumGeneratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class EthereumTests: XCTestCase { 12 | func testGenerator() { 13 | let publicKey = "041a12f855d14451b786716164b8325da324aeed3f840fe77257feadfae2f1b0786105ddc906b6bcafb84a9a142bba69e77ad2f21c877c11f0b29676cbdf767af2" 14 | let publicKeyData = try! Data.from(hexString: publicKey) 15 | let address = try! EthereumGenerator().generate(publicKey: publicKeyData) 16 | 17 | XCTAssertEqual(address.count, 40) 18 | XCTAssertEqual(address, "3f5b765f6a9007a7a08b07c04acd391441045c1d") 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /AddressGeneratorTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /AddressGeneratorTests/KeccakHashTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class KeccakHashTests: XCTestCase { 12 | 13 | func testHash() { 14 | do { 15 | let string = "hello" 16 | let hash = try! KeccakHash().hash(data: string.toData()) 17 | 18 | XCTAssertEqual(hash.count, 32) 19 | try XCTAssertEqual( 20 | hash, 21 | Data.from(hexString: "1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8") 22 | ) 23 | } 24 | } 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /AddressGeneratorTests/KeyPairGeneratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class KeyPairGeneratorTests: XCTestCase { 12 | 13 | func testKeyPairGenerator() { 14 | let pair = try! KeyPairGenerator().generate() 15 | 16 | XCTAssertEqual(pair.privateKey.count, 32) 17 | XCTAssertEqual(pair.publicKey.count, 65) 18 | } 19 | 20 | func testHexDump() { 21 | let pair = try! KeyPairGenerator().generate() 22 | 23 | XCTAssertEqual(try! pair.privateKey.hexDump().count, 65) 24 | XCTAssertEqual(try! pair.publicKey.hexDump().count, 131) 25 | 26 | XCTAssertEqual(try! pair.privateKey.hexDump().toString().count, 64) 27 | XCTAssertEqual(try! pair.publicKey.hexDump().toString().count, 130) 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /AddressGeneratorTests/PublicKeyCompressorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PublicKeyCompressorTests.swift 3 | // AddressGeneratorTests 4 | // 5 | // Created by Khoa Pham on 06.01.2018. 6 | // Copyright © 2018 Khoa Pham. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import AddressGenerator 11 | 12 | class PublicKeyCompressorTests: XCTestCase { 13 | func testCompressor() { 14 | let publicKey = "0482006e9398a6986eda61fe91674c3a108c399475bf1e738f19dfc2db11db1d28130c6b3b28aef9a9c7e7143dac6cf12c09b8444db61679abb1d86f85c038a58c" 15 | let publicKeyData = try! Data.from(hexString: publicKey) 16 | let compressed = PublicKeyCompressor().compress(publicKey: publicKeyData) 17 | let string = try! compressed.hexDump().toString() 18 | 19 | XCTAssertEqual(compressed.count, 33) 20 | XCTAssertEqual(string, "0282006e9398a6986eda61fe91674c3a108c399475bf1e738f19dfc2db11db1d28") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /AddressGeneratorTests/RippleGeneratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class RippleTests: XCTestCase { 12 | func testGenerator() { 13 | let publicKey = "0482006e9398a6986eda61fe91674c3a108c399475bf1e738f19dfc2db11db1d28130c6b3b28aef9a9c7e7143dac6cf12c09b8444db61679abb1d86f85c038a58c" 14 | let publicKeyData = try! Data.from(hexString: publicKey) 15 | let address = try! RippleGenerator().generate(publicKey: publicKeyData) 16 | 17 | XCTAssertEqual(address.count, 34) 18 | XCTAssertEqual(address, "rwqkk7T1h47vj84gkBwHn7HtdmekgsRZwJ") 19 | } 20 | } 21 | 22 | 23 | -------------------------------------------------------------------------------- /AddressGeneratorTests/WalletImportGeneratorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AddressGenerator 3 | // 4 | // Created by Khoa Pham on 14.12.2017. 5 | // Copyright © 2017 Khoa Pham. All rights reserved. 6 | // 7 | 8 | import XCTest 9 | @testable import AddressGenerator 10 | 11 | class WalletImportGeneratorTests: XCTestCase { 12 | func testWalletImportFormatGenerator() { 13 | let privateKey = "896462332ff505dccfd04a61eea9ece054e0a0873d3bd9d92ddd8a0f27c0c275" 14 | let privateKeyData = try! Data.from(hexString: privateKey) 15 | let wif = try! WalletImportFormatGenerator().generate(privateKey: privateKeyData, prefix: 0x80) 16 | 17 | XCTAssertEqual(wif.count, 51) 18 | XCTAssertEqual(wif, "5Jro5XgQ7PCSr3rk8FRvYVqmGtRUr4xj2qSexxvNPVwahEe9R5m") 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Khoa Pham 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.11' 2 | 3 | target 'AddressGenerator' do 4 | use_frameworks! 5 | pod 'Anchors' 6 | pod 'Omnia' 7 | end 8 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Anchors (2.4.0) 3 | - Omnia (3.0.0) 4 | 5 | DEPENDENCIES: 6 | - Anchors 7 | - Omnia 8 | 9 | SPEC REPOS: 10 | https://github.com/cocoapods/specs.git: 11 | - Anchors 12 | - Omnia 13 | 14 | SPEC CHECKSUMS: 15 | Anchors: 75614cac462e063b395386e31eb593a856d831a8 16 | Omnia: 6dcb30832bd69ec18b981bbb8d66f066c38c35eb 17 | 18 | PODFILE CHECKSUM: ee362afd777842c855da1425ab5e2fd14aad2856 19 | 20 | COCOAPODS: 1.7.5 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Address Generator 2 | == 3 | 4 | ❤️ Support my work https://gum.co/ixSBCP ❤️ 5 | 6 | ![](Screenshots/Artboard.png) 7 | 8 | ## Getting started 9 | 10 | ### Your own key pair 11 | 12 | You can go to some websites, create an account and have them manage your online wallets there. It also means that you can lose your money when they are hacked or compromised. Also, some websites make it very difficult to export the private keys. 13 | 14 | Would you give your money safe key to strangers? The same applies for cryptocurrencies, the money is truly yours when only you have the keys. You can generate your own key pair, thanks to `AddressGenerator` 15 | 16 | ### Asymetric cryptography 17 | 18 | A cryptocurrency account, which is based on [Asymmetric cryptography](https://en.wikipedia.org/wiki/Public-key_cryptography), consists of 2 keys: public key and private key. 19 | 20 | - The private key (raw or in [wallet import format](https://en.bitcoin.it/wiki/Wallet_import_format)) is a secret number generated randomly. You spend money by using private key to sign transaction. 21 | - The public key is derived from private key. Your account address is a hash value of this public key. 22 | 23 | It's important that only you own and store these keys securely 💪 24 | 25 | ### Extra dependencies 26 | 27 | Generating wallets with Javascript browsers or `electron.js` apps is a big red flag ‼️ Those are built on top of hundreds of libraries. Even if you're offline, who knows if any of those dependencies are doing evil 😱 28 | 29 | While you're still skeptical, here are some readings 30 | 31 | - [I’m harvesting credit card numbers and passwords from your site. Here’s how.](https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8cb347c5b5) 32 | - [Hunting Malicious npm Packages](https://duo.com/blog/hunting-malicious-npm-packages) 33 | 34 | You deserve a safer solution ♥️ 35 | 36 | ### Features 37 | 38 | `AddressGenerator` features 39 | 40 | - Use pure Swift and C code. No extra dependencies. 41 | - Support macOS 10.11 42 | - Generate key pair using `OpenSSL`. On macOS 10.13, it is [LibreSSL](https://www.libressl.org/) 2.2.7 which is a fork of OpenSSL from 2014. OpenSSL seeds from `/dev/urandom`, which guarantees very good entropy, so your keys are truly random and secure. 43 | - No saving or networking. Your keys are generated and only you know about it. 44 | - Fast 45 | - Support many cryptocurrencies 46 | 47 | ## How to use 48 | 49 | - Download the latest [release](https://github.com/onmyway133/AddressGenerator/releases) 50 | 51 |
52 | 53 |
54 | 55 | - Choose currency, then click "Generate" 56 | - Store address together with public key, private key in a safe place. 57 | 58 | ## Supported currencies 59 | 60 | `AddressGenerator` supports 176 currencies. Here are the list together with how to check balance. 61 | 62 | | Currency | Balance checker | 63 | | ------------- | ------------- | 64 | | Bitcoin | https://blockchain.info/ | 65 | | Ethereum | https://etherscan.io/balancecheck-tool | 66 | | Ripple | https://bithomp.com/explorer/ | 67 | | Litecoin | http://explorer.litecoin.net/ | 68 | | Dash | https://chainz.cryptoid.info/ | 69 | | ... | ... | 70 | | Raiblocks | TODO | 71 | | Stellar | TODO | 72 | | EOS | TODO | 73 | 74 | 75 | ## How does it work 76 | 77 | - Bitcoin and similar coins addresses are based on [Technical background of version 1 Bitcoin addresses](https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses), in form of [Pay 2 Public Key Hash](https://en.bitcoin.it/wiki/Transaction#Pay-to-PubkeyHash) 78 | - Ripple address is based on [XRP Ledger Accounts](https://ripple.com/build/accounts/) 79 | - Ethereum address and [keccak 256](https://en.wikipedia.org/wiki/SHA-3) are based on official [ethash](https://github.com/ethereum/ethash) 80 | - Initial key prefixes are from [WalletGenerator](https://github.com/MichaelMure/WalletGenerator.net) 81 | 82 | ## Donations 83 | 84 | If you find this project helpful, please consider donating 😝 85 | 86 | - Bitcoin: 186hfQqr6ZkNfhs8b7oR927n3Fr9qnCQwU 87 | - Ethereum: 0x7f2eA797329271e1b6f1E518A34f319A884A5A19 88 | 89 | ## Licence 90 | 91 | This project is released under the MIT license. See [LICENSE.md](https://github.com/onmyway133/AddressGenerator/blob/master/LICENSE.md) 92 | -------------------------------------------------------------------------------- /Screenshots/Artboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/Screenshots/Artboard.png -------------------------------------------------------------------------------- /Screenshots/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/Screenshots/demo.png -------------------------------------------------------------------------------- /Screenshots/s1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/Screenshots/s1.png -------------------------------------------------------------------------------- /Screenshots/s2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/Screenshots/s2.png -------------------------------------------------------------------------------- /Screenshots/s3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onmyway133/AddressGenerator/680ee9e764fc15b8874889ea33a95e642c579def/Screenshots/s3.png --------------------------------------------------------------------------------