diff --git a/app/javascript/controllers/settings/nostr_pubkey_controller.js b/app/javascript/controllers/settings/nostr_pubkey_controller.js index 4de30e5..038d7cd 100644 --- a/app/javascript/controllers/settings/nostr_pubkey_controller.js +++ b/app/javascript/controllers/settings/nostr_pubkey_controller.js @@ -1,8 +1,14 @@ import { Controller } from "@hotwired/stimulus" +import { Nostrify } from "nostrify" // Connects to data-controller="settings--nostr-pubkey" export default class extends Controller { - static targets = [ "noExtension", "setPubkey", "pubkeyBech32Input" ] + static targets = [ + "noExtension", + "setPubkey", "pubkeyBech32Input", + "relayList", "relayListStatus", + "profileStatusNip05", "profileStatusLud16" + ] static values = { userAddress: String, pubkeyHex: String, @@ -15,6 +21,14 @@ export default class extends Controller { if (this.hasSetPubkeyTarget) { this.setPubkeyTarget.disabled = false } + + if (this.pubkeyHexValue) { + this.discoverUserOnNostr().then(() => { + this.renderRelayStatus() + this.renderProfileNip05Status() + this.renderProfileLud16Status() + }) + } } else { this.noExtensionTarget.classList.remove("hidden") } @@ -49,8 +63,172 @@ export default class extends Controller { } } + async discoverUserOnNostr () { + this.nip65Relays = await this.findUserRelays() + this.profile = await this.findUserProfile() + } + + async findUserRelays () { + const controller = new AbortController(); + const signal = controller.signal; + const filters = [{ kinds: [10002], authors: [this.pubkeyHexValue], limit: 1 }] + const messages = [] + + for await (const msg of this.discoveryPool.req(filters, { signal })) { + if (msg[0] === 'EVENT') { + if (!messages.find(m => m.id === msg[2].id)) { + messages.push(msg[2]) + } + } + if (msg[0] === 'EOSE') { break } + } + + // Close the relay subscription + controller.abort() + if (messages.length === 0) { return messages } + + const sortedMessages = messages.sort((a, b) => a.createdAt - b.createdAt) + const newestMessage = messages[messages.length - 1] + + return newestMessage.tags.filter(t => t[0] === 'r') + .map(t => { return { url: t[1], marker: t[2] } }) + } + + async findUserProfile () { + const controller = new AbortController(); + const signal = controller.signal; + const filters = [{ kinds: [0], authors: [this.pubkeyHexValue], limit: 1 }] + const messages = [] + + for await (const msg of this.discoveryPool.req(filters, { signal })) { + if (msg[0] === 'EVENT') { + if (!messages.find(m => m.id === msg[2].id)) { + messages.push(msg[2]) + } + } + if (msg[0] === 'EOSE') { break } + } + + // Close the relay subscription + controller.abort() + if (messages.length === 0) { return null } + + const sortedMessages = messages.sort((a, b) => a.createdAt - b.createdAt) + const newestMessage = messages[messages.length - 1] + + return JSON.parse(newestMessage.content) + } + + renderRelayStatus () { + let showStatus + + if (this.nip65Relays.length > 0) { + if (this.relaysContainAccountsRelay) { + showStatus = 'green' + } else { + showStatus = 'orange' + } + } else { + showStatus = 'red' + } + // showStatus = 'red' + + this.relayListStatusTarget + .querySelector(`.status-${showStatus}`) + .classList.remove("hidden") + } + + renderProfileNip05Status () { + let showStatus + + if (this.profile?.nip05) { + if (this.profile.nip05 === this.userAddressValue) { + showStatus = 'green' + } else { + showStatus = 'red' + } + } else { + showStatus = 'orange' + } + + this.profileStatusNip05Target + .querySelector(`.status-${showStatus}`) + .classList.remove("hidden") + } + + renderProfileLud16Status () { + let showStatus + + if (this.profile?.lud16) { + if (this.profile.lud16 === this.userAddressValue) { + showStatus = 'green' + } else { + showStatus = 'red' + } + } else { + showStatus = 'orange' + } + + this.profileStatusLud16Target + .querySelector(`.status-${showStatus}`) + .classList.remove("hidden") + } + + // renderRelayList (relays) { + // const html = relays.map(relay => ` + //
+
+ name="nostr_public_key" class="w-full" /> <%= link_to nostr_pubkey_settings_path, - class: 'btn-md btn-outline text-red-700 relative shrink-0', + class: 'btn-md btn-outline relative grow-0 shrink-0 text-red-700', data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' } do %> Remove <% end %>
<% if current_user.nostr_pubkey.present? %> -- Your user address <%= current_user.address %> is - also a Nostr address now. Use your favorite Nostr app, or for - example metadata.nostr.com, to add this - NIP-05 address to your public profile. -
-- If you use any apps on the Nostr network, you can verify your public key - with us in order to enable Nostr-specific features for your account. + Verify your Nostr public key with us in order to enable Nostr-specific + features for your account.
<% end %> @@ -58,8 +44,8 @@- We recommend Alby, which you can also use for your Lightning - Wallet. + We recommend Alby, which you can also use a wallet for your + Lightning account.