Lightning-Invoice: lnbc1pjcpaakpp5gjs4f626hf8w6slx84xz3wwhlf309z503rjutckdxv6wwg5ldavsdqqcqzpgxqrrs0fppqjaxxw43p7em4g59vedv7pzl76kt0qyjfsp5qcp9de7a7t8h6zs5mcssfaqp4exrnkehqtg2hf0ary3z5cjnasvs9qyyssq55523e4h3cazhkv7f8jqf5qp0n8spykls49crsu5t3m636u3yj4qdqjkdl2nxf6jet5t2r2pfrxmm8rjpqjd3ylrzqq89m4gqt5l6ycqf92c7h Closes: https://github.com/damus-io/damus/issues/940 Signed-off-by: Charlie Fish <contact@charlie.fish> Signed-off-by: William Casarin <jb55@jb55.com> Changelog-Added: Add NIP-42 relay auth support
123 lines
3.6 KiB
Swift
123 lines
3.6 KiB
Swift
//
|
|
// NostrResponse.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2022-04-11.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
struct CommandResult {
|
|
let event_id: NoteId
|
|
let ok: Bool
|
|
let msg: String
|
|
}
|
|
|
|
enum MaybeResponse {
|
|
case bad
|
|
case ok(NostrResponse)
|
|
}
|
|
|
|
enum NostrResponse {
|
|
case event(String, NostrEvent)
|
|
case notice(String)
|
|
case eose(String)
|
|
case ok(CommandResult)
|
|
/// An [NIP-42](https://github.com/nostr-protocol/nips/blob/master/42.md) `auth` challenge.
|
|
///
|
|
/// The associated type of this case is the challenge string sent by the server.
|
|
case auth(String)
|
|
|
|
var subid: String? {
|
|
switch self {
|
|
case .ok:
|
|
return nil
|
|
case .event(let sub_id, _):
|
|
return sub_id
|
|
case .eose(let sub_id):
|
|
return sub_id
|
|
case .notice:
|
|
return nil
|
|
case .auth(let challenge_string):
|
|
return challenge_string
|
|
}
|
|
}
|
|
|
|
static func owned_from_json(json: String) -> NostrResponse? {
|
|
return json.withCString{ cstr in
|
|
let bufsize: Int = max(Int(Double(json.utf8.count) * 4.0), Int(getpagesize()))
|
|
let data = malloc(bufsize)
|
|
|
|
if data == nil {
|
|
let r: NostrResponse? = nil
|
|
return r
|
|
}
|
|
//guard var json_cstr = json.cString(using: .utf8) else { return nil }
|
|
|
|
//json_cs
|
|
var tce = ndb_tce()
|
|
|
|
let len = ndb_ws_event_from_json(cstr, Int32(json.utf8.count), &tce, data, Int32(bufsize), nil)
|
|
if len <= 0 {
|
|
free(data)
|
|
return nil
|
|
}
|
|
|
|
switch tce.evtype {
|
|
case NDB_TCE_OK:
|
|
defer { free(data) }
|
|
|
|
guard let evid_str = sized_cstr(cstr: tce.subid, len: tce.subid_len),
|
|
let evid = hex_decode_noteid(evid_str),
|
|
let msg = sized_cstr(cstr: tce.command_result.msg, len: tce.command_result.msglen) else {
|
|
return nil
|
|
}
|
|
let cr = CommandResult(event_id: evid, ok: tce.command_result.ok == 1, msg: msg)
|
|
|
|
return .ok(cr)
|
|
case NDB_TCE_EOSE:
|
|
defer { free(data) }
|
|
|
|
guard let subid = sized_cstr(cstr: tce.subid, len: tce.subid_len) else {
|
|
return nil
|
|
}
|
|
return .eose(subid)
|
|
case NDB_TCE_EVENT:
|
|
|
|
// Create new Data with just the valid bytes
|
|
guard let note_data = realloc(data, Int(len)) else {
|
|
free(data)
|
|
return nil
|
|
}
|
|
let new_note = note_data.assumingMemoryBound(to: ndb_note.self)
|
|
let note = NdbNote(note: new_note, size: Int(len), owned: true, key: nil)
|
|
|
|
guard let subid = sized_cstr(cstr: tce.subid, len: tce.subid_len) else {
|
|
free(data)
|
|
return nil
|
|
}
|
|
return .event(subid, note)
|
|
case NDB_TCE_NOTICE:
|
|
free(data)
|
|
return .notice("")
|
|
case NDB_TCE_AUTH:
|
|
defer { free(data) }
|
|
|
|
guard let challenge_string = sized_cstr(cstr: tce.subid, len: tce.subid_len) else {
|
|
return nil
|
|
}
|
|
return .auth(challenge_string)
|
|
default:
|
|
free(data)
|
|
return nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func sized_cstr(cstr: UnsafePointer<CChar>, len: Int32) -> String? {
|
|
let msgbuf = Data(bytes: cstr, count: Int(len))
|
|
return String(data: msgbuf, encoding: .utf8)
|
|
}
|
|
|