This PR redesigns the NWC wallet view. A new view is added to introduce zaps to users. The set up wallet view is simplified, with new and existing wallet setup separated. This also adds new NWC features such as getBalance and listTransactions allowing users to see their balance and previous transactions made. Changelog-Added: Added view introducing users to Zaps Changelog-Added: Added new wallet view with balance and transactions list Changelog-Changed: Improved integration with Nostr Wallet Connect wallets Closes: https://github.com/damus-io/damus/issues/2900 Signed-off-by: ericholguin <ericholguin@apache.org> Co-Authored-By: Daniel D’Aquino <daniel@daquino.me> Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
93 lines
3.6 KiB
Swift
93 lines
3.6 KiB
Swift
//
|
|
// WalletConnect.swift
|
|
// damus
|
|
//
|
|
// Created by William Casarin on 2023-03-22.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
struct WalletConnect {}
|
|
|
|
typealias WalletConnectURL = WalletConnect.ConnectURL // Declared to facilitate refactor
|
|
|
|
extension WalletConnect {
|
|
/// Models a decoded NWC URL, containing information to connect to an NWC wallet.
|
|
struct ConnectURL: Equatable {
|
|
let relay: RelayURL
|
|
let keypair: FullKeypair
|
|
let pubkey: Pubkey
|
|
let lud16: String?
|
|
|
|
static func == (lhs: ConnectURL, rhs: ConnectURL) -> Bool {
|
|
return lhs.keypair == rhs.keypair &&
|
|
lhs.pubkey == rhs.pubkey &&
|
|
lhs.relay == rhs.relay
|
|
}
|
|
|
|
func to_url() -> URL {
|
|
var urlComponents = URLComponents()
|
|
urlComponents.scheme = "nostrwalletconnect"
|
|
urlComponents.host = pubkey.hex()
|
|
urlComponents.queryItems = [
|
|
URLQueryItem(name: "relay", value: relay.absoluteString),
|
|
URLQueryItem(name: "secret", value: keypair.privkey.hex())
|
|
]
|
|
|
|
if let lud16 {
|
|
urlComponents.queryItems?.append(URLQueryItem(name: "lud16", value: lud16))
|
|
}
|
|
|
|
return urlComponents.url!
|
|
}
|
|
|
|
init?(str: String) {
|
|
guard let components = URLComponents(string: str),
|
|
components.scheme == "nostrwalletconnect" || components.scheme == "nostr+walletconnect",
|
|
// The line below provides flexibility for both `nostrwalletconnect://` (non-compliant, but commonly used) and `nostrwalletconnect:` (NIP-47 compliant) formats
|
|
let encoded_pubkey = components.path == "" ? components.host : components.path,
|
|
let pubkey = hex_decode_pubkey(encoded_pubkey),
|
|
let items = components.queryItems,
|
|
let relay = items.first(where: { qi in qi.name == "relay" })?.value,
|
|
let relay_url = RelayURL(relay),
|
|
let secret = items.first(where: { qi in qi.name == "secret" })?.value,
|
|
secret.utf8.count == 64,
|
|
let decoded = hex_decode(secret)
|
|
else {
|
|
return nil
|
|
}
|
|
|
|
let privkey = Privkey(Data(decoded))
|
|
guard let our_pk = privkey_to_pubkey(privkey: privkey) else { return nil }
|
|
|
|
let lud16 = items.first(where: { qi in qi.name == "lud16" })?.value
|
|
let keypair = FullKeypair(pubkey: our_pk, privkey: privkey)
|
|
self = ConnectURL(pubkey: pubkey, relay: relay_url, keypair: keypair, lud16: lud16)
|
|
}
|
|
|
|
init(pubkey: Pubkey, relay: RelayURL, keypair: FullKeypair, lud16: String?) {
|
|
self.pubkey = pubkey
|
|
self.relay = relay
|
|
self.keypair = keypair
|
|
self.lud16 = lud16
|
|
}
|
|
}
|
|
|
|
/// Models an NWC wallet transaction
|
|
struct Transaction: Decodable, Equatable, Hashable {
|
|
let type: String
|
|
let invoice: String?
|
|
let description: String?
|
|
let description_hash: String?
|
|
let preimage: String?
|
|
let payment_hash: String?
|
|
let amount: Int64
|
|
let fees_paid: Int64?
|
|
let created_at: UInt64 // unixtimestamp, // invoice/payment creation time
|
|
let expires_at: UInt64? // unixtimestamp, // invoice expiration time, optional if not applicable
|
|
let settled_at: UInt64? // unixtimestamp, // invoice/payment settlement time, optional if unpaid
|
|
//"metadata": {} // generic metadata that can be used to add things like zap/boostagram details for a payer name/comment/etc.
|
|
}
|
|
}
|
|
|