feat: on-chain option on the Zap the Devs button

ReusableZapButton now passes the user's on-chain zap amount choices to
ZapAmountChoicePopup and renders OnchainZapSendDialog when a chip is
tapped. The dialog receives the release note as the zappedEvent, so
the existing split detection picks up the kind:1 release notes' zap
splits and pays the dev team via one Bitcoin tx with N receipts.

The donation card is the canonical multi-recipient on-chain zap flow —
release notes are tagged with weighted splits across the team, the
sender's own pubkey gets filtered out, and the per-recipient share
preview shows live as the amount is typed.

Other callers of ReusableZapButton (DVM zap buttons, etc.) get the
on-chain row automatically since it's driven by the user's settings;
empty on-chain amounts list hides the row, matching prior behavior.
This commit is contained in:
Claude
2026-05-20 20:20:21 +00:00
parent 45aa6044b7
commit a90dd47ed4
@@ -44,6 +44,7 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.vitorpamplona.amethyst.R
import com.vitorpamplona.amethyst.model.Note
import com.vitorpamplona.amethyst.model.User
@@ -59,11 +60,13 @@ import com.vitorpamplona.amethyst.ui.note.ZapIcon
import com.vitorpamplona.amethyst.ui.note.ZappedIcon
import com.vitorpamplona.amethyst.ui.note.payViaIntent
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
import com.vitorpamplona.amethyst.ui.screen.loggedIn.wallet.OnchainZapSendDialog
import com.vitorpamplona.amethyst.ui.stringRes
import com.vitorpamplona.amethyst.ui.theme.ModifierWidth3dp
import com.vitorpamplona.amethyst.ui.theme.Size14Modifier
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
import com.vitorpamplona.amethyst.ui.theme.Size35dp
import com.vitorpamplona.quartz.nip01Core.core.Event
import com.vitorpamplona.quartz.utils.TimeUtils
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@@ -104,6 +107,12 @@ fun ReusableZapButton(
callbacks: ZapButtonCallbacks = ZapButtonCallbacks(),
) {
var wantsToZap by remember { mutableStateOf<ImmutableList<Long>?>(null) }
var onchainZapAmount by remember { mutableStateOf<Long?>(null) }
var showOnchainDialog by remember { mutableStateOf(false) }
val onchainZapAmountChoices by
accountViewModel.account.settings.syncedSettings.zaps.onchainZapAmountChoices
.collectAsStateWithLifecycle()
// Makes sure the user is loaded to get his ln address ahead of time (for DVM buttons)
if (config.showUserFinderSubscription) {
@@ -192,6 +201,25 @@ fun ReusableZapButton(
nav.nav(Route.ManualZapSplitPayment(uid))
}
},
onchainZapAmountChoices = onchainZapAmountChoices,
onOnchainAmount = { amount ->
wantsToZap = null
onchainZapAmount = amount
showOnchainDialog = true
},
)
}
if (showOnchainDialog) {
OnchainZapSendDialog(
accountViewModel = accountViewModel,
onDismiss = {
showOnchainDialog = false
onchainZapAmount = null
},
recipientPubKey = baseNote.author?.pubkeyHex,
zappedEvent = baseNote.toEventHint<Event>(),
prefillAmountSats = onchainZapAmount,
)
}