2019-05-02 16:33:03 -04:00
//
// R e c e i v e I n t e r f a c e C o n t r o l l e r . s w i f t
// B l u e W a l l e t W a t c h E x t e n s i o n
//
// C r e a t e d b y M a r c o s R o d r i g u e z o n 3 / 1 2 / 1 9 .
// C o p y r i g h t © 2 0 1 9 F a c e b o o k . A l l r i g h t s r e s e r v e d .
//
import WatchKit
2019-11-11 01:26:39 -05:00
import WatchConnectivity
2019-05-02 16:33:03 -04:00
import Foundation
import EFQRCode
class ReceiveInterfaceController : WKInterfaceController {
static let identifier = " ReceiveInterfaceController "
private var wallet : Wallet ?
private var isRenderingQRCode : Bool ?
2019-11-11 01:26:39 -05:00
private var receiveMethod : String = " receive "
2020-08-18 22:25:59 -04:00
private var interfaceMode : InterfaceMode = . Address
@IBOutlet weak var addressLabel : WKInterfaceLabel !
2019-05-02 16:33:03 -04:00
@IBOutlet weak var loadingIndicator : WKInterfaceGroup !
2020-08-18 22:25:59 -04:00
@IBOutlet weak var imageInterface : WKInterfaceImage !
2021-09-27 21:27:03 -04:00
private let userActivity : NSUserActivity = NSUserActivity ( activityType : HandoffIdentifier . ReceiveOnchain . rawValue )
2020-08-18 22:25:59 -04:00
2021-09-27 21:27:03 -04:00
override func willActivate ( ) {
super . willActivate ( )
update ( userActivity )
}
2019-05-02 16:33:03 -04:00
override func awake ( withContext context : Any ? ) {
super . awake ( withContext : context )
2019-11-11 01:26:39 -05:00
guard let passedContext = context as ? ( Int , String ) , WatchDataSource . shared . wallets . count >= passedContext . 0 else {
2019-05-02 16:33:03 -04:00
pop ( )
return
}
2019-11-11 01:26:39 -05:00
let identifier = passedContext . 0
2019-05-02 16:33:03 -04:00
let wallet = WatchDataSource . shared . wallets [ identifier ]
self . wallet = wallet
2019-11-11 01:26:39 -05:00
receiveMethod = passedContext . 1
2019-05-02 16:33:03 -04:00
NotificationCenter . default . addObserver ( forName : SpecifyInterfaceController . NotificationName . createQRCode , object : nil , queue : nil ) { [ weak self ] ( notification ) in
self ? . isRenderingQRCode = true
2021-09-09 12:00:11 +01:00
if let wallet = self ? . wallet , wallet . type = = WalletGradient . LightningCustodial . rawValue || wallet . type = = WalletGradient . LightningLDK . rawValue , self ? . receiveMethod = = " createInvoice " , let object = notification . object as ? SpecifyInterfaceController . SpecificQRCodeContent , let amount = object . amount {
2019-05-02 16:33:03 -04:00
self ? . imageInterface . setHidden ( true )
self ? . loadingIndicator . setHidden ( false )
WatchDataSource . requestLightningInvoice ( walletIdentifier : identifier , amount : amount , description : object . description , responseHandler : { ( invoice ) in
DispatchQueue . main . async {
if ( ! invoice . isEmpty ) {
guard let cgImage = EFQRCode . generate (
2019-08-12 23:14:29 -04:00
content : " lightning: \( invoice ) " , inputCorrectionLevel : . h , pointShape : . circle ) else {
2019-05-02 16:33:03 -04:00
return
}
2021-09-27 23:05:45 -04:00
self ? . invalidateUserActivity ( )
2019-05-02 16:33:03 -04:00
let image = UIImage ( cgImage : cgImage )
self ? . loadingIndicator . setHidden ( true )
self ? . imageInterface . setHidden ( false )
self ? . imageInterface . setImage ( nil )
self ? . imageInterface . setImage ( image )
2020-08-18 22:25:59 -04:00
self ? . addressLabel . setText ( invoice )
self ? . interfaceMode = . QRCode
self ? . toggleViewButtonPressed ( )
2019-11-11 01:26:39 -05:00
WCSession . default . sendMessage ( [ " message " : " fetchTransactions " ] , replyHandler : nil , errorHandler : nil )
2019-05-02 16:33:03 -04:00
} else {
2021-07-31 01:38:31 -04:00
self ? . presentAlert ( withTitle : " Error " , message : " Unable to create invoice. Please open BlueWallet on your iPhone and unlock your wallets. " , preferredStyle : . alert , actions : [ WKAlertAction ( title : " OK " , style : . default , handler : { [ weak self ] in
2019-05-02 16:33:03 -04:00
self ? . dismiss ( )
2020-08-17 21:47:48 -04:00
self ? . pop ( )
2019-05-02 16:33:03 -04:00
} ) ] )
}
}
} )
} else {
guard let notificationObject = notification . object as ? SpecifyInterfaceController . SpecificQRCodeContent , let walletContext = self ? . wallet , ! walletContext . receiveAddress . isEmpty , let receiveAddress = self ? . wallet ? . receiveAddress else { return }
2021-09-27 21:27:03 -04:00
self ? . userActivity . userInfo = [ HandOffUserInfoKey . ReceiveOnchain . rawValue : receiveAddress ]
self ? . userActivity . isEligibleForHandoff = true ;
self ? . userActivity . becomeCurrent ( )
if let userActivity = self ? . userActivity {
self ? . update ( userActivity )
}
2019-05-02 16:33:03 -04:00
var address = " bitcoin: \( receiveAddress ) "
var hasAmount = false
if let amount = notificationObject . amount {
address . append ( " ?amount= \( amount ) & " )
hasAmount = true
}
if let description = notificationObject . description {
if ( ! hasAmount ) {
address . append ( " ? " )
}
address . append ( " label= \( description ) " )
}
DispatchQueue . main . async {
guard let cgImage = EFQRCode . generate (
content : address ) else {
return
}
let image = UIImage ( cgImage : cgImage )
self ? . imageInterface . setImage ( nil )
self ? . imageInterface . setImage ( image )
self ? . imageInterface . setHidden ( false )
2020-08-18 22:25:59 -04:00
self ? . addressLabel . setText ( receiveAddress )
self ? . interfaceMode = . QRCode
self ? . toggleViewButtonPressed ( )
2019-05-02 16:33:03 -04:00
self ? . loadingIndicator . setHidden ( true )
self ? . isRenderingQRCode = false
}
}
}
guard ! wallet . receiveAddress . isEmpty , let cgImage = EFQRCode . generate (
2019-11-11 01:26:39 -05:00
content : wallet . receiveAddress ) , receiveMethod != " createInvoice " else {
2019-05-02 16:33:03 -04:00
return
}
let image = UIImage ( cgImage : cgImage )
imageInterface . setImage ( image )
2020-08-18 22:25:59 -04:00
if #available ( watchOSApplicationExtension 6.0 , * ) {
if let image = UIImage ( systemName : " textformat.subscript " ) {
addMenuItem ( with : image , title : " Address " , action : #selector ( toggleViewButtonPressed ) )
} else {
addMenuItem ( with : . shuffle , title : " Address " , action : #selector ( toggleViewButtonPressed ) )
}
} else {
addMenuItem ( with : . shuffle , title : " Address " , action : #selector ( toggleViewButtonPressed ) )
}
addressLabel . setText ( wallet . receiveAddress )
2021-09-27 23:05:45 -04:00
userActivity . userInfo = [ HandOffUserInfoKey . ReceiveOnchain . rawValue : wallet . receiveAddress ]
userActivity . isEligibleForHandoff = true ;
userActivity . becomeCurrent ( )
update ( userActivity )
2019-05-02 16:33:03 -04:00
}
override func didAppear ( ) {
super . didAppear ( )
2021-09-09 12:00:11 +01:00
if ( wallet ? . type = = WalletGradient . LightningCustodial . rawValue || wallet ? . type = = WalletGradient . LightningLDK . rawValue ) && receiveMethod = = " createInvoice " {
2019-05-02 16:33:03 -04:00
if isRenderingQRCode = = nil {
presentController ( withName : SpecifyInterfaceController . identifier , context : wallet ? . identifier )
isRenderingQRCode = false
} else if isRenderingQRCode = = false {
pop ( )
}
}
}
override func didDeactivate ( ) {
super . didDeactivate ( )
NotificationCenter . default . removeObserver ( self , name : SpecifyInterfaceController . NotificationName . createQRCode , object : nil )
2021-09-27 21:27:03 -04:00
userActivity . invalidate ( )
invalidateUserActivity ( )
2019-05-02 16:33:03 -04:00
}
@IBAction func specifyMenuItemTapped ( ) {
presentController ( withName : SpecifyInterfaceController . identifier , context : wallet ? . identifier )
}
2020-08-18 22:25:59 -04:00
@IBAction @objc func toggleViewButtonPressed ( ) {
clearAllMenuItems ( )
switch interfaceMode {
case . Address :
addressLabel . setHidden ( false )
imageInterface . setHidden ( true )
if #available ( watchOSApplicationExtension 6.0 , * ) {
if let image = UIImage ( systemName : " qrcode " ) {
addMenuItem ( with : image , title : " QR Code " , action : #selector ( toggleViewButtonPressed ) )
} else {
addMenuItem ( with : . shuffle , title : " QR Code " , action : #selector ( toggleViewButtonPressed ) )
}
} else {
addMenuItem ( with : . shuffle , title : " QR Code " , action : #selector ( toggleViewButtonPressed ) )
}
case . QRCode :
addressLabel . setHidden ( true )
imageInterface . setHidden ( false )
if #available ( watchOSApplicationExtension 6.0 , * ) {
if let image = UIImage ( systemName : " textformat.subscript " ) {
addMenuItem ( with : image , title : " Address " , action : #selector ( toggleViewButtonPressed ) )
} else {
addMenuItem ( with : . shuffle , title : " Address " , action : #selector ( toggleViewButtonPressed ) )
}
} else {
addMenuItem ( with : . shuffle , title : " Address " , action : #selector ( toggleViewButtonPressed ) )
}
}
interfaceMode = interfaceMode = = . QRCode ? . Address : . QRCode
}
2019-05-02 16:33:03 -04:00
}