Merge branch 'master' into user-cache
This commit is contained in:
@@ -10,7 +10,7 @@ import Foundation
|
||||
class Profile: Codable {
|
||||
var value: [String: AnyCodable]
|
||||
|
||||
init (name: String?, display_name: String?, about: String?, picture: String?, banner: String?, website: String?, lud06: String?, lud16: String?, nip05: String?) {
|
||||
init (name: String?, display_name: String?, about: String?, picture: String?, banner: String?, website: String?, lud06: String?, lud16: String?, nip05: String?, damus_donation: Int?) {
|
||||
self.value = [:]
|
||||
self.name = name
|
||||
self.display_name = display_name
|
||||
@@ -21,6 +21,7 @@ class Profile: Codable {
|
||||
self.lud06 = lud06
|
||||
self.lud16 = lud16
|
||||
self.nip05 = nip05
|
||||
self.damus_donation = damus_donation
|
||||
}
|
||||
|
||||
convenience init(persisted_profile: PersistedProfile) {
|
||||
@@ -39,6 +40,10 @@ class Profile: Codable {
|
||||
return get_val(str)
|
||||
}
|
||||
|
||||
private func int(_ key: String) -> Int? {
|
||||
return get_val(key)
|
||||
}
|
||||
|
||||
private func get_val<T>(_ v: String) -> T? {
|
||||
guard let val = self.value[v] else{
|
||||
return nil
|
||||
@@ -64,6 +69,10 @@ class Profile: Codable {
|
||||
set_val(key, val)
|
||||
}
|
||||
|
||||
private func set_int(_ key: String, _ val: Int?) {
|
||||
set_val(key, val)
|
||||
}
|
||||
|
||||
var reactions: Bool? {
|
||||
get { return get_val("reactions"); }
|
||||
set(s) { set_val("reactions", s) }
|
||||
@@ -89,6 +98,11 @@ class Profile: Codable {
|
||||
set(s) { set_str("about", s) }
|
||||
}
|
||||
|
||||
var damus_donation: Int? {
|
||||
get { return int("damus_donation"); }
|
||||
set(s) { set_int("damus_donation", s) }
|
||||
}
|
||||
|
||||
var picture: String? {
|
||||
get { return str("picture"); }
|
||||
set(s) { set_str("picture", s) }
|
||||
@@ -192,7 +206,7 @@ class Profile: Codable {
|
||||
}
|
||||
|
||||
func make_test_profile() -> Profile {
|
||||
return Profile(name: "jb55", display_name: "Will", about: "Its a me", picture: "https://cdn.jb55.com/img/red-me.jpg", banner: "https://pbs.twimg.com/profile_banners/9918032/1531711830/600x200", website: "jb55.com", lud06: "jb55@jb55.com", lud16: nil, nip05: "jb55@jb55.com")
|
||||
return Profile(name: "jb55", display_name: "Will", about: "Its a me", picture: "https://cdn.jb55.com/img/red-me.jpg", banner: "https://pbs.twimg.com/profile_banners/9918032/1531711830/600x200", website: "jb55.com", lud06: "jb55@jb55.com", lud16: nil, nip05: "jb55@jb55.com", damus_donation: 1)
|
||||
}
|
||||
|
||||
func make_ln_url(_ str: String?) -> URL? {
|
||||
|
||||
@@ -492,11 +492,11 @@ func make_boost_event(pubkey: String, privkey: String, boosted: NostrEvent) -> N
|
||||
return ev
|
||||
}
|
||||
|
||||
func make_like_event(pubkey: String, privkey: String, liked: NostrEvent) -> NostrEvent {
|
||||
func make_like_event(pubkey: String, privkey: String, liked: NostrEvent, content: String = "🤙") -> NostrEvent {
|
||||
var tags: [[String]] = liked.tags.filter { tag in tag.count >= 2 && (tag[0] == "e" || tag[0] == "p") }
|
||||
tags.append(["e", liked.id])
|
||||
tags.append(["p", liked.pubkey])
|
||||
let ev = NostrEvent(content: "🤙", pubkey: pubkey, kind: 7, tags: tags)
|
||||
let ev = NostrEvent(content: content, pubkey: pubkey, kind: 7, tags: tags)
|
||||
ev.calculate_id()
|
||||
ev.sign(privkey: privkey)
|
||||
|
||||
@@ -512,7 +512,12 @@ func zap_target_to_tags(_ target: ZapTarget) -> [[String]] {
|
||||
}
|
||||
}
|
||||
|
||||
func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair, target: ZapTarget, message: String) -> String? {
|
||||
struct PrivateZapRequest {
|
||||
let req: ZapRequest
|
||||
let enc: String
|
||||
}
|
||||
|
||||
func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair, target: ZapTarget, message: String) -> PrivateZapRequest? {
|
||||
// target tags must be the same as zap request target tags
|
||||
let tags = zap_target_to_tags(target)
|
||||
|
||||
@@ -520,10 +525,13 @@ func make_private_zap_request_event(identity: FullKeypair, enc_key: FullKeypair,
|
||||
note.id = calculate_event_id(ev: note)
|
||||
note.sig = sign_event(privkey: identity.privkey, ev: note)
|
||||
|
||||
guard let note_json = encode_json(note) else {
|
||||
guard let note_json = encode_json(note),
|
||||
let enc = encrypt_message(message: note_json, privkey: enc_key.privkey, to_pk: target.pubkey, encoding: .bech32)
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
return encrypt_message(message: note_json, privkey: enc_key.privkey, to_pk: target.pubkey, encoding: .bech32)
|
||||
|
||||
return PrivateZapRequest(req: ZapRequest(ev: note), enc: enc)
|
||||
}
|
||||
|
||||
func decrypt_private_zap(our_privkey: String, zapreq: NostrEvent, target: ZapTarget) -> NostrEvent? {
|
||||
@@ -587,7 +595,30 @@ func generate_private_keypair(our_privkey: String, id: String, created_at: Int64
|
||||
return FullKeypair(pubkey: pubkey, privkey: privkey)
|
||||
}
|
||||
|
||||
func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> NostrEvent? {
|
||||
enum MakeZapRequest {
|
||||
case priv(ZapRequest, PrivateZapRequest)
|
||||
case normal(ZapRequest)
|
||||
|
||||
var private_inner_request: ZapRequest {
|
||||
switch self {
|
||||
case .priv(_, let pzr):
|
||||
return pzr.req
|
||||
case .normal(let zr):
|
||||
return zr
|
||||
}
|
||||
}
|
||||
|
||||
var potentially_anon_outer_request: ZapRequest {
|
||||
switch self {
|
||||
case .priv(let zr, _):
|
||||
return zr
|
||||
case .normal(let zr):
|
||||
return zr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func make_zap_request_event(keypair: FullKeypair, content: String, relays: [RelayDescriptor], target: ZapTarget, zap_type: ZapType) -> MakeZapRequest? {
|
||||
var tags = zap_target_to_tags(target)
|
||||
var relay_tag = ["relays"]
|
||||
relay_tag.append(contentsOf: relays.map { $0.url.id })
|
||||
@@ -597,6 +628,8 @@ func make_zap_request_event(keypair: FullKeypair, content: String, relays: [Rela
|
||||
|
||||
let now = Int64(Date().timeIntervalSince1970)
|
||||
|
||||
var privzap_req: PrivateZapRequest?
|
||||
|
||||
var message = content
|
||||
switch zap_type {
|
||||
case .pub:
|
||||
@@ -614,14 +647,20 @@ func make_zap_request_event(keypair: FullKeypair, content: String, relays: [Rela
|
||||
guard let privreq = make_private_zap_request_event(identity: keypair, enc_key: kp, target: target, message: message) else {
|
||||
return nil
|
||||
}
|
||||
tags.append(["anon", privreq])
|
||||
tags.append(["anon", privreq.enc])
|
||||
message = ""
|
||||
privzap_req = privreq
|
||||
}
|
||||
|
||||
let ev = NostrEvent(content: message, pubkey: kp.pubkey, kind: 9734, tags: tags, createdAt: now)
|
||||
ev.id = calculate_event_id(ev: ev)
|
||||
ev.sig = sign_event(privkey: kp.privkey, ev: ev)
|
||||
return ev
|
||||
let zapreq = ZapRequest(ev: ev)
|
||||
if let privzap_req {
|
||||
return .priv(zapreq, privzap_req)
|
||||
} else {
|
||||
return .normal(zapreq)
|
||||
}
|
||||
}
|
||||
|
||||
func uniq<T: Hashable>(_ xs: [T]) -> [T] {
|
||||
@@ -927,6 +966,28 @@ func first_eref_mention(ev: NostrEvent, privkey: String?) -> Mention? {
|
||||
return nil
|
||||
}
|
||||
|
||||
/**
|
||||
Transforms a `NostrEvent` of known kind `NostrKind.like`to a human-readable emoji.
|
||||
If the known kind is not a `NostrKind.like`, it will return `nil`.
|
||||
If the event content is an empty string or `+`, it will map that to a heart ❤️ emoji.
|
||||
If the event content is a "-", it will map that to a dislike 👎 emoji.
|
||||
Otherwise, it will return the event content at face value without transforming it.
|
||||
*/
|
||||
func to_reaction_emoji(ev: NostrEvent) -> String? {
|
||||
guard ev.known_kind == NostrKind.like else {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch ev.content {
|
||||
case "", "+":
|
||||
return "❤️"
|
||||
case "-":
|
||||
return "👎"
|
||||
default:
|
||||
return ev.content
|
||||
}
|
||||
}
|
||||
|
||||
extension [ReferencedId] {
|
||||
var pRefs: [ReferencedId] {
|
||||
get {
|
||||
|
||||
@@ -22,4 +22,6 @@ enum NostrKind: Int {
|
||||
case list = 30000
|
||||
case zap = 9735
|
||||
case zap_request = 9734
|
||||
case nwc_request = 23194
|
||||
case nwc_response = 23195
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Profiles {
|
||||
qos: .userInteractive,
|
||||
attributes: .concurrent)
|
||||
|
||||
var profiles: [String: TimestampedProfile] = [:]
|
||||
private var profiles: [String: TimestampedProfile] = [:]
|
||||
var validated: [String: NIP05] = [:]
|
||||
var nip05_pubkey: [String: String] = [:]
|
||||
var zappers: [String: String] = [:]
|
||||
@@ -28,6 +28,12 @@ class Profiles {
|
||||
validated[pk]
|
||||
}
|
||||
|
||||
func enumerated() -> EnumeratedSequence<[String: TimestampedProfile]> {
|
||||
return queue.sync {
|
||||
return profiles.enumerated()
|
||||
}
|
||||
}
|
||||
|
||||
func lookup_zapper(pubkey: String) -> String? {
|
||||
zappers[pubkey]
|
||||
}
|
||||
@@ -77,3 +83,9 @@ class Profiles {
|
||||
return Date.now.timeIntervalSince(pull_date) < Profiles.db_freshness_threshold
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func invalidate_zapper_cache(pubkey: String, profiles: Profiles, lnurl: LNUrls) {
|
||||
profiles.zappers.removeValue(forKey: pubkey)
|
||||
lnurl.endpoints.removeValue(forKey: pubkey)
|
||||
}
|
||||
|
||||
@@ -10,21 +10,46 @@ import Foundation
|
||||
public struct RelayInfo: Codable {
|
||||
let read: Bool?
|
||||
let write: Bool?
|
||||
let ephemeral: Bool?
|
||||
|
||||
init(read: Bool, write: Bool, ephemeral: Bool = false) {
|
||||
init(read: Bool, write: Bool) {
|
||||
self.read = read
|
||||
self.write = write
|
||||
self.ephemeral = ephemeral
|
||||
}
|
||||
|
||||
static let rw = RelayInfo(read: true, write: true, ephemeral: false)
|
||||
static let ephemeral = RelayInfo(read: true, write: true, ephemeral: true)
|
||||
static let rw = RelayInfo(read: true, write: true)
|
||||
}
|
||||
|
||||
enum RelayVariant {
|
||||
case regular
|
||||
case ephemeral
|
||||
case nwc
|
||||
}
|
||||
|
||||
public struct RelayDescriptor {
|
||||
public let url: RelayURL
|
||||
public let info: RelayInfo
|
||||
let url: RelayURL
|
||||
let info: RelayInfo
|
||||
let variant: RelayVariant
|
||||
|
||||
init(url: RelayURL, info: RelayInfo, variant: RelayVariant = .regular) {
|
||||
self.url = url
|
||||
self.info = info
|
||||
self.variant = variant
|
||||
}
|
||||
|
||||
var ephemeral: Bool {
|
||||
switch variant {
|
||||
case .regular:
|
||||
return false
|
||||
case .ephemeral:
|
||||
return true
|
||||
case .nwc:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
static func nwc(url: RelayURL) -> RelayDescriptor {
|
||||
return RelayDescriptor(url: url, info: .rw, variant: .nwc)
|
||||
}
|
||||
}
|
||||
|
||||
enum RelayFlags: Int {
|
||||
|
||||
@@ -43,7 +43,7 @@ class RelayPool {
|
||||
}
|
||||
|
||||
var our_descriptors: [RelayDescriptor] {
|
||||
return all_descriptors.filter { d in !(d.info.ephemeral ?? false) }
|
||||
return all_descriptors.filter { d in !d.ephemeral }
|
||||
}
|
||||
|
||||
var all_descriptors: [RelayDescriptor] {
|
||||
@@ -91,7 +91,8 @@ class RelayPool {
|
||||
}
|
||||
}
|
||||
|
||||
func add_relay(_ url: RelayURL, info: RelayInfo) throws {
|
||||
func add_relay(_ desc: RelayDescriptor) throws {
|
||||
let url = desc.url
|
||||
let relay_id = get_relay_id(url)
|
||||
if get_relay(relay_id) != nil {
|
||||
throw RelayError.RelayAlreadyExists
|
||||
@@ -99,8 +100,7 @@ class RelayPool {
|
||||
let conn = RelayConnection(url: url) { event in
|
||||
self.handle_event(relay_id: relay_id, event: event)
|
||||
}
|
||||
let descriptor = RelayDescriptor(url: url, info: info)
|
||||
let relay = Relay(descriptor: descriptor, connection: conn)
|
||||
let relay = Relay(descriptor: desc, connection: conn)
|
||||
self.relays.append(relay)
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ class RelayPool {
|
||||
continue
|
||||
}
|
||||
|
||||
if (relay.descriptor.info.ephemeral ?? false) && skip_ephemeral {
|
||||
if relay.descriptor.ephemeral && skip_ephemeral {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ func add_rw_relay(_ pool: RelayPool, _ url: String) {
|
||||
guard let url = RelayURL(url) else {
|
||||
return
|
||||
}
|
||||
try? pool.add_relay(url, info: RelayInfo.rw)
|
||||
try? pool.add_relay(RelayDescriptor(url: url, info: .rw))
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user