Skip to content

Commit

Permalink
Add Face ID protect account and signed actions #2
Browse files Browse the repository at this point in the history
  • Loading branch information
f0go committed Mar 29, 2022
1 parent e67d78f commit cacd87f
Show file tree
Hide file tree
Showing 8 changed files with 157 additions and 136 deletions.
4 changes: 0 additions & 4 deletions Terra Planet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
5933E9BA27EA19AD00C8D25D /* nodejs-project in Resources */ = {isa = PBXBuildFile; fileRef = 5933E9B927EA19AD00C8D25D /* nodejs-project */; };
5933E9BC27EA22DC00C8D25D /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5933E9BB27EA22DC00C8D25D /* Network.swift */; };
5933E9BE27EA294E00C8D25D /* Balance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5933E9BD27EA294E00C8D25D /* Balance.swift */; };
5933E9C027EA2B1B00C8D25D /* KeyChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5933E9BF27EA2B1B00C8D25D /* KeyChain.swift */; };
5933E9C227EA311200C8D25D /* KeyChainManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5933E9C127EA311200C8D25D /* KeyChainManager.swift */; };
596145F727EDEBFF00026427 /* Anchor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 596145F627EDEBFF00026427 /* Anchor.swift */; };
596145F927EDEC6500026427 /* AnchorActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 596145F827EDEC6500026427 /* AnchorActions.swift */; };
Expand Down Expand Up @@ -128,7 +127,6 @@
5933E9B927EA19AD00C8D25D /* nodejs-project */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "nodejs-project"; sourceTree = "<group>"; };
5933E9BB27EA22DC00C8D25D /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = "<group>"; };
5933E9BD27EA294E00C8D25D /* Balance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Balance.swift; sourceTree = "<group>"; };
5933E9BF27EA2B1B00C8D25D /* KeyChain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChain.swift; sourceTree = "<group>"; };
5933E9C127EA311200C8D25D /* KeyChainManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyChainManager.swift; sourceTree = "<group>"; };
596145F627EDEBFF00026427 /* Anchor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Anchor.swift; sourceTree = "<group>"; };
596145F827EDEC6500026427 /* AnchorActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnchorActions.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -196,7 +194,6 @@
5908BA8027EB492C00AC0ED8 /* Utils */ = {
isa = PBXGroup;
children = (
5933E9BF27EA2B1B00C8D25D /* KeyChain.swift */,
5973AE8C27EC910F00F6F78E /* QR.swift */,
596145FC27EE0A8600026427 /* QR.storyboard */,
5923398327ECB52D00E4DF84 /* Utils.swift */,
Expand Down Expand Up @@ -684,7 +681,6 @@
59A9E40427EB52B200544B62 /* NewWalletInfoVC.swift in Sources */,
5933E9C227EA311200C8D25D /* KeyChainManager.swift in Sources */,
592FA2EA27EDE8B200955BF7 /* AnchorVC.swift in Sources */,
5933E9C027EA2B1B00C8D25D /* KeyChain.swift in Sources */,
59E2728D27EC96DD002F8C1D /* Send.swift in Sources */,
5973AE8D27EC910F00F6F78E /* QR.swift in Sources */,
596145F727EDEBFF00026427 /* Anchor.swift in Sources */,
Expand Down
132 changes: 80 additions & 52 deletions Terra Planet/API/API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -119,91 +119,119 @@ final class API {
}

func send(token: String, amount: String, address: String, callback: @escaping (_ status: Bool) -> Void) {
if let wallet = wallet {
let payload: [String:Any] = [
"fee_token" : "uluna",
"token" : token,
"amount" : amount,
"dst_addr" : address,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(local)wallet/send", data: payload) { response in
if response.status == 200 {
callback(true)
KeyChainManager.shared.loadWallet { status in
if status {
if let wallet = self.wallet {
let payload: [String:Any] = [
"fee_token" : "uluna",
"token" : token,
"amount" : amount,
"dst_addr" : address,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(self.local)wallet/send", data: payload) { response in
if response.status == 200 {
callback(true)
}
else {
callback(false)
}
}
}
else {
callback(false)
}
}
}
else {
callback(false)
else {
callback(false)
}
}
}

func swap(from: String, to: String, amount: String, callback: @escaping (_ status: Bool) -> Void) {
if let wallet = wallet {
let payload: [String:Any] = [
"fee_token" : "uluna",
"src" : from,
"amount" : amount,
"dst" : to,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(local)wallet/swap", data: payload) { response in
if response.status == 200 {
callback(true)
KeyChainManager.shared.loadWallet { status in
if status {
if let wallet = self.wallet {
let payload: [String:Any] = [
"fee_token" : "uluna",
"src" : from,
"amount" : amount,
"dst" : to,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(self.local)wallet/swap", data: payload) { response in
if response.status == 200 {
callback(true)
}
else {
callback(false)
}
}
}
else {
callback(false)
}
}
}
else {
callback(false)
else {
callback(false)
}
}
}

//MARK: Anchor
func anchorDeposit(amount: String, callback: @escaping (_ status: Bool) -> Void) {
if let wallet = wallet {
let payload: [String:Any] = [
"token" : "uusd",
"amount" : amount,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(local)anchor/deposit", data: payload) { response in
if response.status == 200 {
callback(true)
KeyChainManager.shared.loadWallet { status in
if status {
if let wallet = self.wallet {
let payload: [String:Any] = [
"token" : "uusd",
"amount" : amount,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(self.local)anchor/deposit", data: payload) { response in
if response.status == 200 {
callback(true)
}
else {
callback(false)
}
}
}
else {
callback(false)
}
}
}
else {
callback(false)
else {
callback(false)
}
}
}

func anchorWithdraw(amount: String, callback: @escaping (_ status: Bool) -> Void) {
if let wallet = wallet {
let payload: [String:Any] = [
"token" : "uusd",
"amount" : amount,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(local)anchor/withdraw", data: payload) { response in
if response.status == 200 {
callback(true)
KeyChainManager.shared.loadWallet { status in
if status {
if let wallet = self.wallet {
let payload: [String:Any] = [
"token" : "uusd",
"amount" : amount,
"mnemonic" : wallet.mnemonic
]
Network.shared.post("\(self.local)anchor/withdraw", data: payload) { response in
if response.status == 200 {
callback(true)
}
else {
callback(false)
}
}
}
else {
callback(false)
}
}
}
else {
callback(false)
else {
callback(false)
}
}
}

Expand Down
84 changes: 68 additions & 16 deletions Terra Planet/API/KeyChainManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,31 +11,83 @@ import SwiftyJSON
final class KeyChainManager {
static let shared = KeyChainManager()

private let service = "TerraPlanet"
private let account = "Account"

func saveWallet(wallet: Wallet) {
let json:JSON = ["address":wallet.address, "mnemonic":wallet.mnemonic]
var data: Data?
try? data = json.rawData()
if data != nil {
let status = KeyChain.save(key: "wallet", data: data!)
print("status: ", status)
let _ = deleteWallet()
let dic = ["address":wallet.address,"mnemonic":wallet.mnemonic]
let valueData: Data = NSKeyedArchiver.archivedData(withRootObject: dic)
let sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, .userPresence, nil)!

let insert_query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccessControl: sacObject,
kSecValueData: valueData,
kSecUseAuthenticationUI: kSecUseAuthenticationUIAllow,
kSecAttrService: service,
kSecAttrAccount: account
]
let insert_status = SecItemAdd(insert_query as CFDictionary, nil)
if insert_status == errSecSuccess {
print("Inserted successfully.")
}
else {
print("INSERT Error: \(insert_status).")
}
}

func loadWallet() -> Bool {
if let receivedData = KeyChain.load(key: "wallet") {
if let json = try? JSON(data: receivedData) {
print("Wallet Loaded: \(json)")
API.shared.wallet = Wallet(address: json["address"].stringValue, mnemonic: json["mnemonic"].stringValue, coins: [:])
return true
func loadWallet(callback: @escaping (_ status: Bool) -> Void) {
DispatchQueue.global().async {
let select_query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: self.service,
kSecAttrAccount: self.account,
kSecReturnData: true,
kSecUseOperationPrompt: "Touch to Unlock"
]
var extractedData: CFTypeRef?
let select_status = SecItemCopyMatching(select_query, &extractedData)
if select_status == errSecSuccess {
if let retrievedData = extractedData as? Data,
let credentials: [String : String] = NSKeyedUnarchiver.unarchiveObject(with: retrievedData) as? [String : String] {
print(credentials)
if let address = credentials["address"], let mnemonic = credentials["mnemonic"] {
API.shared.wallet = Wallet(address: address, mnemonic: mnemonic, coins: [:])
callback(true)
}
else {
callback(false)
}
}
else {
callback(false)
}
}
else {
print("Error loading Wallet")
return false
callback(false)
}
}
else {
print("No stored Wallet")
}

func deleteWallet() -> Bool {
let delete_query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: service,
kSecAttrAccount: account,
kSecReturnData: false
]
let delete_status = SecItemDelete(delete_query)
if delete_status == errSecSuccess {
print("Deleted successfully.")
return true
} else if delete_status == errSecItemNotFound {
print("Nothing to delete.")
return false
} else {
print("DELETE Error: \(delete_status).")
return false
}
}

}
3 changes: 3 additions & 0 deletions Terra Planet/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
NodeRunner.runNode()
}
}
KeyChainManager.shared.loadWallet { status in
print(status)
}
}

func applicationDidBecomeActive(_ application: UIApplication) {
Expand Down
2 changes: 2 additions & 0 deletions Terra Planet/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSFaceIDUsageDescription</key>
<string>Terra Planer use Face ID to protect your account</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UILaunchStoryboardName</key>
Expand Down
62 changes: 0 additions & 62 deletions Terra Planet/Utils/KeyChain.swift

This file was deleted.

4 changes: 3 additions & 1 deletion Terra Planet/Views/Start/First.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ extension FirstVC {

func loadWallet(callback: @escaping (_ hasWallet: Bool) -> Void) {
waitServer {
callback(KeyChainManager.shared.loadWallet())
KeyChainManager.shared.loadWallet { status in
callback(status)
}
}
}

Expand Down
Loading

0 comments on commit cacd87f

Please sign in to comment.