Huge refactor to add better structure to the project. Separating features with their associated view and model structure. This should be better organization and will allow us to improve the overall architecture in the future. I forsee many more improvements that can follow this change. e.g. MVVM Arch As well as cleaning up duplicate, unused, functionality. Many files have global functions that can also be moved or be renamed. damus/ ├── Features/ │ ├── <Feature>/ │ │ ├── Views/ │ │ └── Models/ ├── Shared/ │ ├── Components/ │ ├── Media/ │ ├── Buttons/ │ ├── Extensions/ │ ├── Empty Views/ │ ├── ErrorHandling/ │ ├── Modifiers/ │ └── Utilities/ ├── Core/ │ ├── Nostr/ │ ├── NIPs/ │ ├── DIPs/ │ ├── Types/ │ ├── Networking/ │ └── Storage/ Signed-off-by: ericholguin <ericholguin@apache.org>
116 lines
2.5 KiB
Swift
116 lines
2.5 KiB
Swift
//
|
|
// NostrLink.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2022-05-05.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
|
|
enum NostrLink: Equatable {
|
|
case ref(RefId)
|
|
case filter(NostrFilter)
|
|
case script([UInt8])
|
|
case invoice(String)
|
|
}
|
|
|
|
func encode_pubkey_uri(_ pubkey: Pubkey) -> String {
|
|
return "p:" + pubkey.hex()
|
|
}
|
|
|
|
// TODO: bech32 and relay hints
|
|
func encode_event_id_uri(_ noteid: NoteId) -> String {
|
|
return "e:" + noteid.hex()
|
|
}
|
|
|
|
func parse_nostr_ref_uri_type(_ p: Parser) -> String? {
|
|
if parse_char(p, "p") {
|
|
return "p"
|
|
}
|
|
|
|
if parse_char(p, "e") {
|
|
return "e"
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func parse_hexstr(_ p: Parser, len: Int) -> String? {
|
|
var i: Int = 0
|
|
|
|
if len % 2 != 0 {
|
|
return nil
|
|
}
|
|
|
|
let start = p.pos
|
|
|
|
while i < len {
|
|
guard parse_hex_char(p) != nil else {
|
|
p.pos = start
|
|
return nil
|
|
}
|
|
i += 1
|
|
}
|
|
|
|
return String(substring(p.str, start: start, end: p.pos))
|
|
}
|
|
|
|
func decode_nostr_bech32_uri(_ s: String) -> NostrLink? {
|
|
guard let obj = Bech32Object.parse(s) else {
|
|
return nil
|
|
}
|
|
|
|
switch obj {
|
|
case .nsec(let privkey):
|
|
guard let pubkey = privkey_to_pubkey(privkey: privkey) else { return nil }
|
|
return .ref(.pubkey(pubkey))
|
|
case .npub(let pubkey):
|
|
return .ref(.pubkey(pubkey))
|
|
case .note(let id):
|
|
return .ref(.event(id))
|
|
case .nscript(let data):
|
|
return .script(data)
|
|
case .naddr(let naddr):
|
|
return .ref(.naddr(naddr))
|
|
case .nevent(let nevent):
|
|
return .ref(.event(nevent.noteid))
|
|
case .nprofile(let nprofile):
|
|
return .ref(.pubkey(nprofile.author))
|
|
case .nrelay(_):
|
|
return .none
|
|
}
|
|
}
|
|
|
|
func decode_nostr_uri(_ s: String) -> NostrLink? {
|
|
let uri = remove_nostr_uri_prefix(s)
|
|
|
|
let parts = uri.split(separator: ":")
|
|
.reduce(into: Array<String>()) { acc, str in
|
|
guard let decoded = str.removingPercentEncoding else {
|
|
return
|
|
}
|
|
acc.append(decoded)
|
|
return
|
|
}
|
|
|
|
if parts.count >= 2 {
|
|
switch parts[0] {
|
|
case "t":
|
|
return .filter(NostrFilter(hashtag: [parts[1].lowercased()]))
|
|
case "lightning":
|
|
return .invoice(parts[1])
|
|
default:
|
|
break
|
|
}
|
|
}
|
|
|
|
guard parts.count == 1 else {
|
|
return nil
|
|
}
|
|
|
|
let part = parts[0]
|
|
|
|
return decode_nostr_bech32_uri(part)
|
|
}
|