Auto-add receiving address on wallet setup

This commit is contained in:
Matthew Remmel
2025-09-15 09:11:57 -04:00
committed by hodlbod
parent 290274d6c8
commit 6e238f98c0
7 changed files with 241 additions and 34 deletions
+5 -28
View File
@@ -1,22 +1,13 @@
<script lang="ts">
import {nthNe} from "@welshman/lib"
import type {Profile} from "@welshman/util"
import {
getTag,
makeEvent,
makeProfile,
editProfile,
createProfile,
isPublishedProfile,
uniqTags,
} from "@welshman/util"
import {Router} from "@welshman/router"
import {pubkey, profilesByPubkey, publishThunk} from "@welshman/app"
import {getTag, makeProfile} from "@welshman/util"
import {pubkey, profilesByPubkey} from "@welshman/app"
import Button from "@lib/components/Button.svelte"
import ProfileEditForm from "@app/components/ProfileEditForm.svelte"
import {clearModals} from "@app/util/modal"
import {pushToast} from "@app/util/toast"
import {PROTECTED, getMembershipUrls, userMembership} from "@app/core/state"
import {PROTECTED} from "@app/core/state"
import {updateProfile} from "../core/commands"
const profile = $profilesByPubkey.get($pubkey!) || makeProfile()
const shouldBroadcast = !getTag(PROTECTED, profile.event?.tags || [])
@@ -25,21 +16,7 @@
const back = () => history.back()
const onsubmit = ({profile, shouldBroadcast}: {profile: Profile; shouldBroadcast: boolean}) => {
const router = Router.get()
const template = isPublishedProfile(profile) ? editProfile(profile) : createProfile(profile)
const scenarios = [router.FromRelays(getMembershipUrls($userMembership))]
if (shouldBroadcast) {
scenarios.push(router.FromUser(), router.Index())
template.tags = template.tags.filter(nthNe(0, "-"))
} else {
template.tags = uniqTags([...template.tags, PROTECTED])
}
const event = makeEvent(template.kind, template)
const relays = router.merge(scenarios).getUrls()
publishThunk({event, relays})
updateProfile({profile, shouldBroadcast})
pushToast({message: "Your profile has been updated!"})
clearModals()
}
@@ -0,0 +1,61 @@
<script lang="ts">
import {getWalletAddress} from "@welshman/util"
import Button from "@lib/components/Button.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {updateProfile} from "@app/core/commands"
import {clearModals} from "@app/util/modal"
import {userProfile, session} from "@welshman/app"
import {makeProfile, type NWCInfo} from "@welshman/util"
const lud16 = getWalletAddress($session!.wallet!)
const confirm = async () => {
const profile = $userProfile || makeProfile()
loading = true
try {
await updateProfile({profile: {...profile, lud16}})
clearModals()
} finally {
loading = false
}
}
const cancel = () => {
clearModals()
}
let loading = $state(false)
</script>
<div class="column gap-4">
<ModalHeader>
{#snippet title()}
Set as Receiving Address?
{/snippet}
</ModalHeader>
{#if $userProfile?.lud16}
<p>
Your current receiving address is different from the one provided by your connected wallet.
</p>
<p>
Would you like to update your receiving address to <span class="text-primary">{lud16}</span>?
</p>
{:else}
<p>
You don't currently have a receiving address set, which means other people can't send you
lightning payments.
</p>
<p>Would you like to use the one associated with your connected wallet?</p>
{/if}
<ModalFooter>
<Button class="btn btn-neutral" onclick={cancel} disabled={loading}>No, skip this</Button>
<Button class="btn btn-primary" onclick={confirm} disabled={loading}>
<Spinner {loading}>Yes, set as receiving address</Spinner>
</Button>
</ModalFooter>
</div>
+10 -3
View File
@@ -3,7 +3,8 @@
import {nwc} from "@getalby/sdk"
import {sleep, assoc} from "@welshman/lib"
import type {NWCInfo} from "@welshman/util"
import {pubkey, updateSession} from "@welshman/app"
import {pubkey, userProfile, updateSession, profilesByPubkey} from "@welshman/app"
import {makeProfile} from "@welshman/util"
import Link from "@lib/components/Link.svelte"
import Cpu from "@assets/icons/cpu-bolt.svg?dataurl"
import Lock from "@assets/icons/lock-keyhole.svg?dataurl"
@@ -15,11 +16,13 @@
import Scanner from "@lib/components/Scanner.svelte"
import Spinner from "@lib/components/Spinner.svelte"
import Field from "@lib/components/Field.svelte"
import Divider from "@lib/components/Divider.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import {getWebLn} from "@app/core/commands"
import {pushToast} from "@app/util/toast"
import {pushModal} from "@app/util/modal"
import WalletAsReceivingAddress from "@app/components/WalletAsReceivingAddress.svelte"
import Divider from "@src/lib/components/Divider.svelte"
const back = () => history.back()
@@ -76,6 +79,10 @@
await sleep(400)
back()
if (info.lud16 && info.lud16 !== $userProfile?.lud16) {
pushModal(WalletAsReceivingAddress)
}
}
} catch (e) {
console.error(e)
@@ -109,7 +116,7 @@
<div>Connect a Wallet</div>
{/snippet}
{#snippet info()}
Use Nostr Wallet Connect to send Bitcoin payments over Bolt.
Use Nostr Wallet Connect to send Bitcoin payments over lightning.
{/snippet}
</ModalHeader>
{#if getWebLn()}
@@ -0,0 +1,100 @@
<script lang="ts">
import {getWalletAddress} from "@welshman/util"
import {session, userProfile} from "@welshman/app"
import Icon from "@lib/components/Icon.svelte"
import Button from "@lib/components/Button.svelte"
import ModalHeader from "@lib/components/ModalHeader.svelte"
import ModalFooter from "@lib/components/ModalFooter.svelte"
import Wallet from "@assets/icons/wallet.svg?dataurl"
import CheckCircle from "@assets/icons/check-circle.svg?dataurl"
import CloseCircle from "@assets/icons/close-circle.svg?dataurl"
import {updateProfile} from "@app/core/commands"
import {pushToast} from "@app/util/toast"
const back = () => history.back()
let address = $state($userProfile?.lud16 || "")
let isLoading = $state(false)
const walletLud16 = $derived($session?.wallet ? getWalletAddress($session.wallet) : undefined)
const useWalletAddress = () => {
if (walletLud16) {
address = walletLud16
}
}
const save = async () => {
isLoading = true
try {
await updateProfile({
profile: {
...$userProfile,
lud06: undefined,
lud16: address.trim() || undefined,
},
})
back()
} catch (error) {
pushToast({theme: "error", message: "Failed to update profile"})
} finally {
isLoading = false
}
}
</script>
<div class="column gap-4">
<ModalHeader>
{#snippet title()}
Update Lightning Address
{/snippet}
{#snippet info()}
Update your lightning address for receiving payments.
{/snippet}
</ModalHeader>
<div class="column gap-4">
<div class="column gap-2">
<span> Lightning Address </span>
<input
type="text"
placeholder="user@domain.com"
bind:value={address}
class="input input-bordered flex w-full"
disabled={isLoading} />
<p class="text-xs opacity-75">
You can enter one manually or use your connected wallet's address (if available). Leave
empty to remove your lightning address
</p>
</div>
{#if walletLud16 && walletLud16 !== address}
<div class="card bg-base-200 p-4">
<div class="flex items-center justify-between gap-3">
<div class="column gap-1">
<div class="flex items-center gap-2">
<Icon icon={Wallet} size={4} />
<span class="text-sm font-medium">Wallet Address</span>
</div>
<p class="text-xs opacity-75">{walletLud16}</p>
</div>
<Button class="btn btn-outline btn-sm" onclick={useWalletAddress} disabled={isLoading}>
Use This
</Button>
</div>
</div>
{/if}
</div>
<ModalFooter>
<Button class="btn btn-neutral" onclick={back} disabled={isLoading}>Cancel</Button>
<Button class="btn btn-primary" onclick={save} disabled={isLoading}>
{#if isLoading}
<span class="loading loading-spinner loading-sm"></span>
{:else}
<Icon icon={CheckCircle} />
{/if}
Save Changes
</Button>
</ModalFooter>
</div>