Browse Source

Wallet Selector

Closes: #107
Changelog-Added: lightning wallet selector
post-button-style
William Casarin 2 years ago
parent
commit
3405742350
  1. 4
      damus.xcodeproj/project.pbxproj
  2. 21
      damus/Assets.xcassets/bluewallet.imageset/Contents.json
  3. BIN
      damus/Assets.xcassets/bluewallet.imageset/bluewallet.png
  4. 21
      damus/Assets.xcassets/cashapp.imageset/Contents.json
  5. BIN
      damus/Assets.xcassets/cashapp.imageset/cashapp.png
  6. 21
      damus/Assets.xcassets/lnlink.imageset/Contents.json
  7. BIN
      damus/Assets.xcassets/lnlink.imageset/lnlink.png
  8. 21
      damus/Assets.xcassets/muun.imageset/Contents.json
  9. BIN
      damus/Assets.xcassets/muun.imageset/muun.png
  10. 21
      damus/Assets.xcassets/phoenix.imageset/Contents.json
  11. BIN
      damus/Assets.xcassets/phoenix.imageset/phoenix.png
  12. 21
      damus/Assets.xcassets/strike.imageset/Contents.json
  13. BIN
      damus/Assets.xcassets/strike.imageset/strike.png
  14. 21
      damus/Assets.xcassets/walletofsatoshi.imageset/Contents.json
  15. BIN
      damus/Assets.xcassets/walletofsatoshi.imageset/walletofsatoshi.png
  16. 21
      damus/Assets.xcassets/zebedee.imageset/Contents.json
  17. BIN
      damus/Assets.xcassets/zebedee.imageset/zebedee.png
  18. 21
      damus/Assets.xcassets/zeusln.imageset/Contents.json
  19. BIN
      damus/Assets.xcassets/zeusln.imageset/zeus.png
  20. 14
      damus/Components/InvoiceView.swift
  21. 4
      damus/Info.plist
  22. 14
      damus/Util/Constants.swift
  23. 19
      damus/Views/ProfileView.swift
  24. 91
      damus/Views/SelectWalletView.swift

4
damus.xcodeproj/project.pbxproj

@ -131,6 +131,7 @@
4CEE2AF9280B2EAC00AB5EEF /* PowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */; }; 4CEE2AF9280B2EAC00AB5EEF /* PowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */; };
4CEE2B02280B39E800AB5EEF /* EventActionBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */; }; 4CEE2B02280B39E800AB5EEF /* EventActionBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */; };
6C7DE41F2955169800E66263 /* Vault in Frameworks */ = {isa = PBXBuildFile; productRef = 6C7DE41E2955169800E66263 /* Vault */; }; 6C7DE41F2955169800E66263 /* Vault in Frameworks */ = {isa = PBXBuildFile; productRef = 6C7DE41E2955169800E66263 /* Vault */; };
BAB68BED29543FA3007BA466 /* SelectWalletView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */; };
E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E990020E2955F837003BBC5A /* EditMetadataView.swift */; }; E990020F2955F837003BBC5A /* EditMetadataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E990020E2955F837003BBC5A /* EditMetadataView.swift */; };
E9E4ED0B295867B900DD7078 /* ThreadV2View.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */; }; E9E4ED0B295867B900DD7078 /* ThreadV2View.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@ -311,6 +312,7 @@
4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileName.swift; sourceTree = "<group>"; }; 4CEE2AF6280B2DEA00AB5EEF /* ProfileName.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileName.swift; sourceTree = "<group>"; };
4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PowView.swift; sourceTree = "<group>"; }; 4CEE2AF8280B2EAC00AB5EEF /* PowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PowView.swift; sourceTree = "<group>"; };
4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventActionBar.swift; sourceTree = "<group>"; }; 4CEE2B01280B39E800AB5EEF /* EventActionBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventActionBar.swift; sourceTree = "<group>"; };
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectWalletView.swift; sourceTree = "<group>"; };
E990020E2955F837003BBC5A /* EditMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMetadataView.swift; sourceTree = "<group>"; }; E990020E2955F837003BBC5A /* EditMetadataView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditMetadataView.swift; sourceTree = "<group>"; };
E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadV2View.swift; sourceTree = "<group>"; }; E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadV2View.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -482,6 +484,7 @@
4C216F33286F5ACD00040376 /* DMView.swift */, 4C216F33286F5ACD00040376 /* DMView.swift */,
4C06670028FC7C5900038D2A /* RelayView.swift */, 4C06670028FC7C5900038D2A /* RelayView.swift */,
E990020E2955F837003BBC5A /* EditMetadataView.swift */, E990020E2955F837003BBC5A /* EditMetadataView.swift */,
BAB68BEC29543FA3007BA466 /* SelectWalletView.swift */,
E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */, E9E4ED0A295867B900DD7078 /* ThreadV2View.swift */,
); );
path = Views; path = Views;
@ -811,6 +814,7 @@
4C3AC79F2833115300E1F516 /* FollowButtonView.swift in Sources */, 4C3AC79F2833115300E1F516 /* FollowButtonView.swift in Sources */,
4C3BEFD22819DB9B00B3DE84 /* ProfileModel.swift in Sources */, 4C3BEFD22819DB9B00B3DE84 /* ProfileModel.swift in Sources */,
4C0A3F93280F66F5000448DE /* ReplyMap.swift in Sources */, 4C0A3F93280F66F5000448DE /* ReplyMap.swift in Sources */,
BAB68BED29543FA3007BA466 /* SelectWalletView.swift in Sources */,
3169CAE6294E69C000EE4006 /* EmptyTimelineView.swift in Sources */, 3169CAE6294E69C000EE4006 /* EmptyTimelineView.swift in Sources */,
4C3EA64928FF597700C48A62 /* bech32.c in Sources */, 4C3EA64928FF597700C48A62 /* bech32.c in Sources */,
4C90BD162839DB54008EE7EF /* NostrMetadata.swift in Sources */, 4C90BD162839DB54008EE7EF /* NostrMetadata.swift in Sources */,

21
damus/Assets.xcassets/bluewallet.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "bluewallet.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/bluewallet.imageset/bluewallet.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

21
damus/Assets.xcassets/cashapp.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "cashapp.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/cashapp.imageset/cashapp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

21
damus/Assets.xcassets/lnlink.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "lnlink.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/lnlink.imageset/lnlink.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

21
damus/Assets.xcassets/muun.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "muun.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/muun.imageset/muun.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

21
damus/Assets.xcassets/phoenix.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "phoenix.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/phoenix.imageset/phoenix.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

21
damus/Assets.xcassets/strike.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "strike.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/strike.imageset/strike.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

21
damus/Assets.xcassets/walletofsatoshi.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "walletofsatoshi.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/walletofsatoshi.imageset/walletofsatoshi.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

21
damus/Assets.xcassets/zebedee.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "zebedee.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/zebedee.imageset/zebedee.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

21
damus/Assets.xcassets/zeusln.imageset/Contents.json

@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "zeus.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

BIN
damus/Assets.xcassets/zeusln.imageset/zeus.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

14
damus/Components/InvoiceView.swift

@ -12,13 +12,13 @@ struct InvoiceView: View {
@Environment(\.colorScheme) var colorScheme @Environment(\.colorScheme) var colorScheme
let invoice: Invoice let invoice: Invoice
@State var showingSelectWallet: Bool = false
@State var inv: String = ""
var PayButton: some View { var PayButton: some View {
Button { Button {
guard let url = URL(string: "lightning:" + invoice.string) else { inv = invoice.string
return showingSelectWallet = true
}
UIApplication.shared.open(url)
} label: { } label: {
RoundedRectangle(cornerRadius: 20) RoundedRectangle(cornerRadius: 20)
.foregroundColor(colorScheme == .light ? .black : .white) .foregroundColor(colorScheme == .light ? .black : .white)
@ -28,6 +28,10 @@ struct InvoiceView: View {
.foregroundColor(colorScheme == .light ? .white : .black) .foregroundColor(colorScheme == .light ? .white : .black)
} }
} }
.buttonStyle(.bordered)
.onTapGesture {
// Temporary solution so that the "pay" button can be clicked (Yes we need an empty tap gesture)
}
} }
var body: some View { var body: some View {
@ -49,6 +53,8 @@ struct InvoiceView: View {
.zIndex(5.0) .zIndex(5.0)
} }
.padding() .padding()
}.sheet(isPresented: $showingSelectWallet, onDismiss: {showingSelectWallet = false}) {
SelectWalletView(showingSelectWallet: $showingSelectWallet, invoice: $inv)
} }
} }
} }

4
damus/Info.plist

@ -15,6 +15,10 @@
</array> </array>
</dict> </dict>
</array> </array>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>lightning</string>
</array>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>
<dict> <dict>
<key>NSAllowsArbitraryLoads</key> <key>NSAllowsArbitraryLoads</key>

14
damus/Util/Constants.swift

@ -24,4 +24,18 @@ public class Constants {
NostrEvent(id: UUID().description, content: "Hello World! This is so cool!", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"), NostrEvent(id: UUID().description, content: "Hello World! This is so cool!", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
NostrEvent(id: UUID().description, content: "Bonjour Le Monde", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"), NostrEvent(id: UUID().description, content: "Bonjour Le Monde", pubkey: "3efdaebb1d8923ebd99c9e7ace3b4194ab45512e2be79c1b7d68d9243e0d2681"),
] ]
static let WALLETS = """
[
{"id": 0, "name": "Strike", "link": "strike:", "appStoreLink": "https://apps.apple.com/us/app/strike-bitcoin-payments/id1488724463", "image": "strike"},
{"id": 1, "name": "Cash App", "link": "squarecash://", "appStoreLink": "https://apps.apple.com/us/app/cash-app/id711923939", "image": "cashapp"},
{"id": 2, "name": "Muun", "link": "muun:", "appStoreLink": "https://apps.apple.com/us/app/muun-wallet/id1482037683", "image": "muun"},
{"id": 3, "name": "Blue Wallet", "link": "bluewallet:lightning:", "appStoreLink": "https://apps.apple.com/us/app/bluewallet-bitcoin-wallet/id1376878040", "image": "bluewallet"},
{"id": 4, "name": "Wallet Of Satoshi", "link": "walletofsatoshi:lightning:", "appStoreLink": "https://apps.apple.com/us/app/wallet-of-satoshi/id1438599608", "image": "walletofsatoshi"},
{"id": 5, "name": "Zebedee", "link": "zebedee:lightning:", "appStoreLink": "https://apps.apple.com/us/app/zebedee-wallet/id1484394401", "image": "zebedee"},
{"id": 6, "name": "Zeus LN", "link": "zeusln:lightning:", "appStoreLink": "https://apps.apple.com/us/app/zeus-ln/id1456038895", "image": "zeusln"},
{"id": 7, "name": "LNLink", "link": "lnlink://", "appStoreLink": "https://testflight.apple.com/join/aNY4yuuZ", "image": "lnlink"},
{"id": 8, "name": "Phoenix", "link": "phoenix://", "appStoreLink": "https://apps.apple.com/us/app/phoenix-wallet/id1544097028", "image": "phoenix"},
]
""".data(using: .utf8)!
} }

19
damus/Views/ProfileView.swift

@ -119,6 +119,8 @@ struct ProfileView: View {
@StateObject var profile: ProfileModel @StateObject var profile: ProfileModel
@StateObject var followers: FollowersModel @StateObject var followers: FollowersModel
@State private var showingEditProfile = false @State private var showingEditProfile = false
@State var showingSelectWallet: Bool = false
@State var inv: String = ""
@State var is_zoomed: Bool = false @State var is_zoomed: Bool = false
@Environment(\.dismiss) var dismiss @Environment(\.dismiss) var dismiss
@ -126,9 +128,14 @@ struct ProfileView: View {
//@EnvironmentObject var profile: ProfileModel //@EnvironmentObject var profile: ProfileModel
func LNButton(_ url: URL, profile: Profile) -> some View { func LNButton(lud06: String?, lud16: String?, profile: Profile) -> some View {
Button(action: { Button(action: {
UIApplication.shared.open(url) if let l = lud06 {
inv = l
} else {
inv = lud16 ?? ""
}
showingSelectWallet = true
}) { }) {
Image(systemName: "bolt.circle") Image(systemName: "bolt.circle")
.symbolRenderingMode(.palette) .symbolRenderingMode(.palette)
@ -141,6 +148,8 @@ struct ProfileView: View {
Label("Copy LNURL", systemImage: "doc.on.doc") Label("Copy LNURL", systemImage: "doc.on.doc")
} }
} }
}.sheet(isPresented: $showingSelectWallet, onDismiss: {showingSelectWallet = false}) {
SelectWalletView(showingSelectWallet: $showingSelectWallet, invoice: $inv)
} }
} }
@ -170,10 +179,10 @@ struct ProfileView: View {
} }
Spacer() Spacer()
if let profile = data { if let profile = data {
if let lnuri = profile.lightning_uri { if (profile.lud06 != nil || profile.lud16 != nil) {
LNButton(lnuri, profile: profile) LNButton(lud06: profile.lud06, lud16: profile.lud16, profile: profile)
} }
} }

91
damus/Views/SelectWalletView.swift

@ -0,0 +1,91 @@
//
// SelectWalletView.swift
// damus
//
// Created by Suhail Saqan on 12/22/22.
//
import SwiftUI
struct WalletItem : Decodable, Identifiable, Hashable {
var id: Int
var name : String
var link : String
var appStoreLink : String
var image: String
}
struct SelectWalletView: View {
@Binding var showingSelectWallet: Bool
@Binding var invoice: String
@Environment(\.openURL) private var openURL
@State var invoice_copied: Bool = false
let generator = UIImpactFeedbackGenerator(style: .light)
let walletItems = try! JSONDecoder().decode([WalletItem].self, from: Constants.WALLETS)
var body: some View {
NavigationView {
Form {
Section("Copy invoice") {
HStack {
Text(invoice).font(.body)
.lineLimit(2)
.truncationMode(.tail)
Spacer()
Image(systemName: self.invoice_copied ? "checkmark.circle" : "doc.on.doc").foregroundColor(.blue)
}.clipShape(RoundedRectangle(cornerRadius: 5)).onTapGesture {
UIPasteboard.general.string = invoice
self.invoice_copied = true
generator.impactOccurred()
}
}
Section("Select a lightning wallet"){
List{
Button() {
if let url = URL(string: "lightning:\(invoice)"), UIApplication.shared.canOpenURL(url) {
openURL(url)
}
} label: {
HStack {
Text("Default Wallet").font(.body).foregroundColor(.blue)
}
}.buttonStyle(.plain)
ForEach(walletItems, id: \.self) { wallet in
Button() {
if let url = URL(string: "\(wallet.link)\(invoice)"), UIApplication.shared.canOpenURL(url) {
openURL(url)
} else {
if let url = URL(string: wallet.appStoreLink), UIApplication.shared.canOpenURL(url) {
openURL(url)
}
}
} label: {
HStack {
Image(wallet.image).resizable().frame(width: 32.0, height: 32.0,alignment: .center).cornerRadius(5)
Text(wallet.name).font(.body)
}
}.buttonStyle(.plain)
}
}.padding(.vertical, 2.5)
}
}.navigationBarTitle(Text("Pay the lightning invoice"), displayMode: .inline).navigationBarItems(trailing: Button(action: {
self.showingSelectWallet = false
}) {
Text("Done").bold()
})
}
}
}
struct SelectWalletView_Previews: PreviewProvider {
@State static var show: Bool = true
@State static var invoice: String = ""
static var previews: some View {
SelectWalletView(showingSelectWallet: $show, invoice: $invoice)
}
}
Loading…
Cancel
Save