mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-08-08 23:54:39 +00:00
Merge pull request #3720 from vitorpamplona/claude/bolt12-zaps-nip-naming-qzw8zi
Rename NIP-XX to NIP-B1 for BOLT12 Zaps specification
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# NWC BOLT12 payments (nostr-wallet-connect/nwc#2)
|
||||
|
||||
Status: **scoping** — no code yet. Depends on NIP-2421 (this branch) and the
|
||||
Status: **scoping** — no code yet. Depends on NIP-B1 (this branch) and the
|
||||
unmerged `nostr-wallet-connect/nwc#2` (adds `pay`/`receive` to NIP-47).
|
||||
|
||||
## Ecosystem status (2026-07-25) — the wallet gap for real testing
|
||||
@@ -10,7 +10,7 @@ A real NWC-321 (`pay`/`receive`) service exists —
|
||||
— which confirms the protocol we built (Phase 0) is real and adopted. **But it is
|
||||
LND-backed:** its `pay` "selects and pays a BOLT11 `lightning` instruction from a
|
||||
BIP-321 URI" and "BOLT12 `lno` instructions are not supported by this LND backend."
|
||||
So it returns no BOLT12 invoice and no `payer_proof`, and can't drive the NIP-2421
|
||||
So it returns no BOLT12 invoice and no `payer_proof`, and can't drive the NIP-B1
|
||||
zap loop. The blocker is the **node backend**, not the protocol: a CLN- or
|
||||
LDK-backed NWC-321 service (CLN has full BOLT12 and leads the payer-proof draft
|
||||
bolts#1346) would support `lno` + return `payer_proof`. Until one exists, the
|
||||
@@ -97,7 +97,7 @@ but is **not** wired into the pay path — we'd add the gate ourselves.
|
||||
kind-10058 offer and the wallet supports `pay`, offer a BOLT12 zap.
|
||||
1. Build + sign kind-9737 intent (amount, offer, p, e/a/k, zap_id, content).
|
||||
2. `pay` with `payment=bitcoin:?lno=<offer>`, `amount`,
|
||||
`payer_note="nostr:nipXX:<intent-id>"`.
|
||||
`payer_note="nostr:nipB1:<intent-id>"`.
|
||||
3. On success with a `payer_proof`, `Bolt12ZapEvent.build(intent, payerProof,
|
||||
payerPubKey = own | null for anon)`, sign, publish to the recipient's inbox
|
||||
relays.
|
||||
@@ -114,8 +114,8 @@ but is **not** wired into the pay path — we'd add the gate ourselves.
|
||||
1. **`payer_note` → `invreq_payer_note` is NOT guaranteed by nwc#2.** The spec only
|
||||
says "if `payer_note` is not empty, the selected instruction MUST support
|
||||
payer-provided messages" — it never states the note lands in the BOLT12
|
||||
`invreq_payer_note`. NIP-2421 binds the zap to the intent through exactly that
|
||||
field (`invreq_payer_note == nostr:nipXX:<intent-id>`). If a wallet routes
|
||||
`invreq_payer_note`. NIP-B1 binds the zap to the intent through exactly that
|
||||
field (`invreq_payer_note == nostr:nipB1:<intent-id>`). If a wallet routes
|
||||
`payer_note` elsewhere, the returned `payer_proof` fails our validator and the
|
||||
9736 is worthless. **Phase 2 feasibility hinges on this** — needs confirmation
|
||||
in the nwc thread / a reference wallet, or a follow-up to nwc#2 to nail it down.
|
||||
@@ -129,7 +129,7 @@ but is **not** wired into the pay path — we'd add the gate ourselves.
|
||||
`quartz/plans/2026-07-23-bolt12-zap-interop-vectors.md`). Real wallet
|
||||
(selective-disclosure) proofs now reconstruct and verify, so a bound zap counts
|
||||
locally as `cryptoVerified = true`.
|
||||
4. **Maturity.** Both nwc#2 and NIP-2421 are unmerged; few/no wallets implement
|
||||
4. **Maturity.** Both nwc#2 and NIP-B1 are unmerged; few/no wallets implement
|
||||
`pay` today. Gate hard on capability (Phase 3) and keep the intent fallback.
|
||||
|
||||
## Resolution of risks #1/#2 (nwc#2 maintainer, 2026-07-24)
|
||||
@@ -138,7 +138,7 @@ Asked on the nwc#2 thread. Maintainer confirmed:
|
||||
|
||||
- **`payer_note` → `invreq_payer_note`**: "that is the intention" for BOLT12 (the
|
||||
field doubles as a general memo). So our zap binding
|
||||
(`invreq_payer_note == nostr:nipXX:<intent-id>`) is the intended target.
|
||||
(`invreq_payer_note == nostr:nipB1:<intent-id>`) is the intended target.
|
||||
- **`payer_proof`**: "should be returned for successful bolt12 payments"; the
|
||||
"optional if unavailable" wording only covers non-BOLT12 instruction types.
|
||||
|
||||
@@ -160,7 +160,7 @@ Chosen: full integration into the zap pipeline, preferring BOLT12 when the
|
||||
recipient offers it.
|
||||
|
||||
- `Account.sendBolt12Zap(...)` — signs a 9737 intent (ephemeral key for anonymous),
|
||||
pays over NWC with `payer_note = nostr:nipXX:<intent-id>`, and only on a proof
|
||||
pays over NWC with `payer_note = nostr:nipB1:<intent-id>`, and only on a proof
|
||||
that passes `Bolt12ZapValidator` self-consumes + publishes the 9736 via
|
||||
`computeRelayListToBroadcast`. No proof / invalid proof → "paid, no receipt".
|
||||
- `ZapPaymentHandler.zap()` resolves each recipient's kind:10058 offer and
|
||||
|
||||
@@ -70,7 +70,7 @@ import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.follow.CommunityListEvent
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
|
||||
import com.vitorpamplona.quartz.nip85TrustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
||||
@@ -369,9 +369,9 @@ import com.vitorpamplona.quartz.nipA0VoiceMessages.BaseVoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceReplyEvent
|
||||
import com.vitorpamplona.quartz.nipB0WebBookmarks.WebBookmarkEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.builder.Bolt12ZapBuilder
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipC7Chats.ChatEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.builder.Bolt12ZapBuilder
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.utils.DualCase
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||
@@ -1455,7 +1455,7 @@ class Account(
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a NIP-XX BOLT12 zap to [recipientPubKey] over the default NWC wallet.
|
||||
* Sends a NIP-B1 BOLT12 zap to [recipientPubKey] over the default NWC wallet.
|
||||
*
|
||||
* Signs a kind 9737 intent, pays [offer] via the nwc#2 `pay` method with the
|
||||
* intent-bound `payer_note`, then — only if the wallet returns a payer proof that
|
||||
|
||||
@@ -75,7 +75,7 @@ import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.follow.CommunityListEvent
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
|
||||
import com.vitorpamplona.quartz.nip85TrustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
@@ -392,6 +392,10 @@ import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallOfferEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRejectEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRenegotiateEvent
|
||||
import com.vitorpamplona.quartz.nipB0WebBookmarks.WebBookmarkEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidator
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomServersEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.chain.OnchainBackend
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
@@ -401,10 +405,6 @@ import com.vitorpamplona.quartz.nipF4Podcasts.authored.AuthoredPodcastsEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.favorites.FavoritePodcastsListEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidator
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.episode.Podcasting20EpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.trailer.Podcasting20TrailerEvent
|
||||
import com.vitorpamplona.quartz.utils.DualCase
|
||||
@@ -473,7 +473,7 @@ object LocalCache : ILocalCache, ICacheProvider {
|
||||
val onchainZapResolver = OnchainZapResolver(this)
|
||||
|
||||
/**
|
||||
* NIP-XX BOLT12 zap validator. Unlike onchain zaps, BOLT12 proof verification
|
||||
* NIP-B1 BOLT12 zap validator. Unlike onchain zaps, BOLT12 proof verification
|
||||
* is synchronous (a self-contained `lnp` payer proof), so `consume(Bolt12ZapEvent)`
|
||||
* validates inline and needs no async resolver.
|
||||
*/
|
||||
@@ -1294,7 +1294,7 @@ object LocalCache : ILocalCache, ICacheProvider {
|
||||
}
|
||||
|
||||
is Bolt12ZapEvent -> {
|
||||
// NIP-XX BOLT12 zaps target an event (e), an addressable event (a),
|
||||
// NIP-B1 BOLT12 zaps target an event (e), an addressable event (a),
|
||||
// or just the recipient profile (p) — same shape as onchain zaps.
|
||||
buildList {
|
||||
event.zappedEvent()?.let { checkGetOrCreateNote(it)?.let { add(it) } }
|
||||
@@ -2718,7 +2718,7 @@ object LocalCache : ILocalCache, ICacheProvider {
|
||||
|
||||
if (!(wasVerified || justVerify(event))) return false
|
||||
|
||||
// NIP-XX validation is fully synchronous: zap-event structure, the embedded
|
||||
// NIP-B1 validation is fully synchronous: zap-event structure, the embedded
|
||||
// kind:9737 intent match, and the `lnp` payer-proof binding + crypto. A failed
|
||||
// validation drops the zap entirely — it never contributes to a zap total.
|
||||
// The outer event signature was already verified above (wasVerified/justVerify),
|
||||
|
||||
+2
-2
@@ -24,7 +24,7 @@ import com.vitorpamplona.amethyst.model.AccountSettings
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.NoteState
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
@@ -37,7 +37,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* The logged-in user's NIP-XX BOLT12 offer list (kind 10058) as live account state,
|
||||
* The logged-in user's NIP-B1 BOLT12 offer list (kind 10058) as live account state,
|
||||
* mirroring [com.vitorpamplona.amethyst.model.nipA3PaymentTargets.NipA3PaymentTargetsState].
|
||||
* Exposes the current offers as a [flow], persists them across restarts (via
|
||||
* [AccountSettings]), and publishes updates with [saveOffers].
|
||||
|
||||
@@ -77,7 +77,7 @@ class ZapPaymentHandler(
|
||||
val user: User? = null,
|
||||
)
|
||||
|
||||
/** A recipient routed over BOLT12 (NIP-XX): they publish a kind:10058 [offer] and we hold an NWC wallet. */
|
||||
/** A recipient routed over BOLT12 (NIP-B1): they publish a kind:10058 [offer] and we hold an NWC wallet. */
|
||||
data class Bolt12Recipient(
|
||||
val user: User,
|
||||
val offer: String,
|
||||
@@ -442,7 +442,7 @@ class ZapPaymentHandler(
|
||||
}
|
||||
|
||||
/**
|
||||
* BOLT12 zap rail (NIP-XX). For each recipient that publishes a kind:10058 offer,
|
||||
* BOLT12 zap rail (NIP-B1). For each recipient that publishes a kind:10058 offer,
|
||||
* signs a 9737 intent, pays the offer over NWC with the intent-bound `payer_note`,
|
||||
* and (if the returned proof validates) publishes a 9736 zap — see
|
||||
* [Account.sendBolt12Zap]. Fire-and-forget like [payViaNWC]: dispatch is optimistic
|
||||
|
||||
+1
-1
@@ -61,9 +61,9 @@ import com.vitorpamplona.quartz.nip71Video.VideoVerticalEvent
|
||||
import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallOfferEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipC7Chats.ChatEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.CancellationException
|
||||
|
||||
+1
-1
@@ -52,8 +52,8 @@ import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nip78AppData.AppSpecificDataEvent
|
||||
import com.vitorpamplona.quartz.nip85TrustedAssertions.list.TrustProviderListEvent
|
||||
import com.vitorpamplona.quartz.nip96FileStorage.config.FileServersEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomServersEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
|
||||
val AccountInfoAndListsFromKeyKinds =
|
||||
listOf(
|
||||
|
||||
+1
-1
@@ -56,9 +56,9 @@ import com.vitorpamplona.quartz.nip84Highlights.HighlightEvent
|
||||
import com.vitorpamplona.quartz.nip88Polls.poll.PollEvent
|
||||
import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent
|
||||
import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipC7Chats.ChatEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
/**
|
||||
* Kinds that notify me about activity on MY messages inside a NIP-29 group — reactions, replies
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ import com.vitorpamplona.quartz.nip56Reports.ReportEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip58Badges.award.BadgeAwardEvent
|
||||
import com.vitorpamplona.quartz.nip72ModCommunities.approval.CommunityPostApprovalEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.mapOfSet
|
||||
|
||||
val RepliesAndReactionsToAddressesKinds1 =
|
||||
|
||||
+1
-1
@@ -43,8 +43,8 @@ import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip88Polls.response.PollResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.contentDiscoveryResponse.NIP90ContentDiscoveryResponseEvent
|
||||
import com.vitorpamplona.quartz.nip90Dvms.status.NIP90StatusEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.mapOfSet
|
||||
|
||||
val RepliesAndReactionsKinds =
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ import com.vitorpamplona.quartz.nip38UserStatus.StatusEvent
|
||||
import com.vitorpamplona.quartz.nip39ExtIdentities.ExternalIdentitiesEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.info.NutzapInfoEvent
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.utils.mapOfSet
|
||||
|
||||
val UserMetadataForKeyKinds =
|
||||
|
||||
+2
-2
@@ -25,14 +25,14 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
* Edits the logged-in user's NIP-XX BOLT12 offer list (kind 10058). Mirrors
|
||||
* Edits the logged-in user's NIP-B1 BOLT12 offer list (kind 10058). Mirrors
|
||||
* [com.vitorpamplona.amethyst.ui.actions.paymentTargets.PaymentTargetsViewModel];
|
||||
* each entry is a canonical raw `lno1...` offer string.
|
||||
*/
|
||||
|
||||
@@ -44,7 +44,7 @@ import com.vitorpamplona.amethyst.ui.theme.Size25dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size35Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdStartPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.WidthAuthorPictureModifier
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@@ -351,12 +351,12 @@ import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.BaseVoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipC0CodeSnippets.CodeSnippetEvent
|
||||
import com.vitorpamplona.quartz.nipC7Chats.ChatEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.episode.Podcasting20EpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.metadata.Podcasting20PodcastMetadata
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.trailer.Podcasting20TrailerEvent
|
||||
|
||||
@@ -550,7 +550,7 @@ fun payViaIntent(
|
||||
* parameter of a BIP21/BIP321 bitcoin URI (`bitcoin:?lno=lno1…`), where the on-chain
|
||||
* address is optional so a Lightning-only offer stands on its own. The wallet resolves
|
||||
* the offer, collects the amount, and completes the payment; this is a plain intent,
|
||||
* not a NIP-57/NIP-XX zap, so it produces no Nostr receipt.
|
||||
* not a NIP-57/NIP-B1 zap, so it produces no Nostr receipt.
|
||||
*/
|
||||
fun payViaBolt12Intent(
|
||||
offer: String,
|
||||
|
||||
@@ -40,11 +40,11 @@ import com.vitorpamplona.amethyst.ui.note.ZapIcon
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size25dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.bitcoinColor
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import java.text.NumberFormat
|
||||
|
||||
/**
|
||||
* Standalone card for a NIP-XX BOLT12 zap (kind 9736), styled like the NIP-57
|
||||
* Standalone card for a NIP-B1 BOLT12 zap (kind 9736), styled like the NIP-57
|
||||
* lightning-zap card but labeled BOLT12. The sender is the `P` payer tag (or the
|
||||
* event pubkey when anonymous); the amount comes straight off the validated
|
||||
* `amount` tag — no LNURL provider or private-zap decryption is involved.
|
||||
|
||||
+1
-1
@@ -1207,7 +1207,7 @@ class AccountViewModel(
|
||||
/**
|
||||
* Pays a recipient's BOLT12 [offer] over the default NWC wallet using the nwc#2
|
||||
* `pay` method, wrapping it as a BIP321 `bitcoin:?lno=` instruction. This is a
|
||||
* plain payment, not a NIP-XX zap (no Nostr receipt); the outcome is surfaced as
|
||||
* plain payment, not a NIP-B1 zap (no Nostr receipt); the outcome is surfaced as
|
||||
* a toast. Callers should gate on [hasNwcWallet].
|
||||
*/
|
||||
fun payBolt12OfferViaNwc(
|
||||
|
||||
+1
-1
@@ -26,8 +26,8 @@ import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip75ZapGoals.GoalEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
/**
|
||||
* Fetches the NIP-75 zap goal referenced by a live stream plus the zap receipts
|
||||
|
||||
+1
-1
@@ -28,8 +28,8 @@ import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessa
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.clip.LiveActivitiesClipEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.raid.LiveActivitiesRaidEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
fun filterMessagesToLiveActivities(
|
||||
channel: LiveActivitiesChannel,
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessa
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.presence.MeetingRoomPresenceEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
/**
|
||||
* Per-room state for every wire subscription scoped to a single
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessa
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.meetingSpaces.MeetingSpaceEvent
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.presence.MeetingRoomPresenceEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
|
||||
+1
-1
@@ -40,8 +40,8 @@ import com.vitorpamplona.quartz.nip18Reposts.GenericRepostEvent
|
||||
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
+1
-1
@@ -86,11 +86,11 @@ import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceReplyEvent
|
||||
import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipC7Chats.ChatEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
|
||||
+1
-1
@@ -26,8 +26,8 @@ import com.vitorpamplona.amethyst.service.relays.SincePerRelayMap
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.client.pool.RelayBasedFilter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
val UserProfileZapReceiverKinds = listOf(LnZapEvent.KIND, OnchainZapEvent.KIND, Bolt12ZapEvent.KIND)
|
||||
|
||||
|
||||
+1
-1
@@ -68,7 +68,7 @@ import com.vitorpamplona.amethyst.ui.stringRes
|
||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size20Modifier
|
||||
import com.vitorpamplona.amethyst.ui.theme.ZeroPadding
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
|
||||
+1
-1
@@ -31,8 +31,8 @@ import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.BigDecimal
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
|
||||
+1
-1
@@ -163,13 +163,13 @@ import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.VoiceReplyEvent
|
||||
import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent
|
||||
import com.vitorpamplona.quartz.nipB0WebBookmarks.WebBookmarkEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomAuthorizationEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomServersEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.authored.AuthoredPodcastsEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.favorites.FavoritePodcastsListEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
/** Returns the `@StringRes` id for the translated kind name, or -1 if unknown. */
|
||||
@Suppress("DEPRECATION")
|
||||
|
||||
+1
-1
@@ -344,12 +344,12 @@ import com.vitorpamplona.quartz.nip94FileMetadata.FileHeaderEvent
|
||||
import com.vitorpamplona.quartz.nip99Classifieds.ClassifiedsEvent
|
||||
import com.vitorpamplona.quartz.nipA0VoiceMessages.BaseVoiceEvent
|
||||
import com.vitorpamplona.quartz.nipA4PublicMessages.PublicMessageEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipC0CodeSnippets.CodeSnippetEvent
|
||||
import com.vitorpamplona.quartz.nipC7Chats.ChatEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.episode.Podcasting20EpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.metadata.Podcasting20PodcastMetadata
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.trailer.Podcasting20TrailerEvent
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ import com.vitorpamplona.quartz.nip47WalletConnect.rpc.Response
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.streaming.LiveActivitiesEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
import kotlinx.coroutines.CompletableDeferred
|
||||
import kotlinx.coroutines.async
|
||||
|
||||
+1
-1
@@ -672,7 +672,7 @@ output then also reports `paid` + the preimage.
|
||||
| `amy zap user USER SATS [--comment X] [--anon\|--private] [--with NDEBIT] [--timeout SECS]` | Profile zap: build the zap request and fetch a BOLT11 from USER's LN service. |
|
||||
| `amy zap event EVENT-ID SATS [--comment X] [--anon\|--private] [--with NDEBIT] [--timeout SECS]` | Same, attributed to a specific event (must be in the local store). Zap splits are honored — one invoice per recipient. |
|
||||
|
||||
### BOLT12 zaps (NIP-XX)
|
||||
### BOLT12 zaps (NIP-B1)
|
||||
|
||||
BOLT12 zaps (kinds 9736/9737, offers in kind:10058). amy has no NWC payment
|
||||
rail, so sending is a **two-step, out-of-band** flow: `bolt12 intent` signs the
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ Status legend: ✅ shipped · 📦 logic lives in `commons/`, needs a command ·
|
||||
| Buzz workspaces (`amy buzz`) | ✅ | `BuzzCommands` — post/read the kind:40002 stream timeline, `attest` (offline NIP-OA), `console` (decrypt+aggregate kind:44200 turn metrics via the shared `AgentFleetAggregator`), `personas` (kind:30175). Join/leave reuse `amy relaygroup` (Buzz workspaces are NIP-29 groups). |
|
||||
| NIP-51 lists (bookmarks, mute, follow sets) | 🆕 | `amethyst/model/nip51Lists/` |
|
||||
| NIP-57 zaps (send) | ✅ partial | `ZapCommand` — `zap user`/`zap event` build the kind:9734 request and fetch the BOLT11 (zap splits honored, one invoice per recipient); `--with NDEBIT` auto-pays through a CLINK debit pointer. Receipt (kind:9735) verification still 🆕. |
|
||||
| BOLT12 zaps (NIP-XX, kinds 9736/9737/10058) | ✅ partial | `Bolt12Commands` + `Bolt12SendCommands` over shared `commons` `Bolt12ZapActions` — `bolt12 decode` (offer/proof), `verify` (validate a kind:9736), `offer get/set` (kind:10058), and the two-step send `intent`→`zap` (out-of-band proof, since amy has no NWC rail). Interop harness + NWC-fetched proofs still 🆕. |
|
||||
| BOLT12 zaps (NIP-B1, kinds 9736/9737/10058) | ✅ partial | `Bolt12Commands` + `Bolt12SendCommands` over shared `commons` `Bolt12ZapActions` — `bolt12 decode` (offer/proof), `verify` (validate a kind:9736), `offer get/set` (kind:10058), and the two-step send `intent`→`zap` (out-of-band proof, since amy has no NWC rail). Interop harness + NWC-fetched proofs still 🆕. |
|
||||
| NIP-65 outbox model queries | ✅ | `OutboxCommand` — `amy outbox USER [--refresh]`, cache-first. |
|
||||
| CLINK offers + debits (`amy offer` / `amy debit`) | ✅ | `OfferCommands` + `DebitCommands` — pointer decode, NIP-05 discover, kind:21001/21002 round-trips, `offer pay --with NDEBIT` end-to-end settlement. `--timeout` is SECONDS. |
|
||||
| Geochat (Bitchat geohash, ephemeral kind:20000) | ✅ | `GeochatCommands` — listen/send/keys with per-geohash throwaway identity + geo-nearest relay routing; doubles as the Bitchat interop harness. |
|
||||
|
||||
@@ -750,7 +750,7 @@ private fun printUsage() {
|
||||
| [--comment X] [--anon|--private] event (must be in local store)
|
||||
| [--timeout SECS]
|
||||
|
|
||||
|BOLT12 zaps (NIP-XX):
|
||||
|BOLT12 zaps (NIP-B1):
|
||||
| bolt12 decode LNO1|LNP1 decode a BOLT12 offer or payer proof
|
||||
| bolt12 verify EVENT-ID validate a kind:9736 zap in the local store
|
||||
| bolt12 offer get USER fetch + show a user's kind:10058 offers
|
||||
|
||||
@@ -28,13 +28,13 @@ import com.vitorpamplona.amethyst.commons.actions.Bolt12ZapActions
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
/**
|
||||
* `amy bolt12 …` — NIP-XX BOLT12 zaps from the command line, for headless interop
|
||||
* `amy bolt12 …` — NIP-B1 BOLT12 zaps from the command line, for headless interop
|
||||
* testing of the quartz BOLT12 stack.
|
||||
*
|
||||
* Sub-verbs:
|
||||
@@ -54,7 +54,7 @@ import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
object Bolt12Commands {
|
||||
val USAGE: String =
|
||||
"""
|
||||
|BOLT12 zaps (NIP-XX):
|
||||
|BOLT12 zaps (NIP-B1):
|
||||
| bolt12 decode LNO1|LNP1 decode an offer or payer proof to fields
|
||||
| bolt12 verify EVENT-ID validate a kind:9736 zap in the local store
|
||||
| bolt12 offer get USER fetch + show a user's kind:10058 offers
|
||||
|
||||
@@ -28,9 +28,9 @@ import com.vitorpamplona.amethyst.commons.actions.Bolt12ZapActions
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.filters.Filter
|
||||
import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidation
|
||||
|
||||
/**
|
||||
* The BOLT12 send-side sub-verbs of `amy bolt12` (split from [Bolt12Commands] to keep
|
||||
|
||||
+10
-10
@@ -24,19 +24,19 @@ import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.builder.Bolt12ZapBuilder
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidator
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.builder.Bolt12ZapBuilder
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidator
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
|
||||
/**
|
||||
* NIP-XX BOLT12 zap building, decoding, and validation — the shared, UI-free
|
||||
* NIP-B1 BOLT12 zap building, decoding, and validation — the shared, UI-free
|
||||
* surface a non-Android caller (amy CLI, interop harnesses) drives.
|
||||
*
|
||||
* Assembly-only: it re-exposes [Bolt12ZapBuilder] / [Bolt12ZapValidator] and the
|
||||
|
||||
+2
-2
@@ -23,12 +23,12 @@ package com.vitorpamplona.amethyst.commons.model
|
||||
import androidx.compose.runtime.Stable
|
||||
|
||||
/**
|
||||
* Per-payment NIP-XX BOLT12 zap entry attached to a target Note.
|
||||
* Per-payment NIP-B1 BOLT12 zap entry attached to a target Note.
|
||||
*
|
||||
* Unlike NIP-BC onchain zaps (which carry an async chain-verification state
|
||||
* machine), a BOLT12 zap is validated **synchronously** at consumption time —
|
||||
* the `lnp` payer proof is a self-contained cryptographic settlement proof — so
|
||||
* every entry stored here has already passed [com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidator]
|
||||
* every entry stored here has already passed [com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidator]
|
||||
* and its amount is counted directly, the same way a NIP-57 lightning zap
|
||||
* receipt's amount is.
|
||||
*
|
||||
|
||||
@@ -287,7 +287,7 @@ open class Note(
|
||||
private set
|
||||
|
||||
/**
|
||||
* NIP-XX BOLT12 zaps (kind 9736) targeting this note.
|
||||
* NIP-B1 BOLT12 zaps (kind 9736) targeting this note.
|
||||
* Key: the payer proof's `invoice_payment_hash` (hex) — the spec's dedup key,
|
||||
* so two zap events proving the same settled payment collapse to one entry.
|
||||
* Value: entry with the source Bolt12ZapEvent note (so `source.author` is the
|
||||
@@ -829,7 +829,7 @@ open class Note(
|
||||
} else {
|
||||
// Same verification status: dedup by the settled payment and, if amounts
|
||||
// differ, keep the LOWER — so a re-publish with a bigger amount tag can't
|
||||
// inflate the total (NIP-XX). Both share the same cryptoVerified flag.
|
||||
// inflate the total (NIP-B1). Both share the same cryptoVerified flag.
|
||||
if (entry.amountMillisats < existing.amountMillisats) entry else existing
|
||||
}
|
||||
if (merged == existing) return@withLock false
|
||||
@@ -846,10 +846,10 @@ open class Note(
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a NIP-XX BOLT12 zap targeting this note. [source] is the kind:9736
|
||||
* Register a NIP-B1 BOLT12 zap targeting this note. [source] is the kind:9736
|
||||
* event's own note — `source.author` is the payer shown in the reactions
|
||||
* gallery and notifications. [amountMillisats] and [cryptoVerified] come from
|
||||
* the synchronous [com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidator]
|
||||
* the synchronous [com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidator]
|
||||
* verdict; the caller MUST only call this for a `Valid` result. Deduplicated by
|
||||
* [paymentHashHex] (the proof's `invoice_payment_hash`).
|
||||
*/
|
||||
@@ -1189,7 +1189,7 @@ open class Note(
|
||||
sumOfAmounts += BigDecimal(entry.claimedSats)
|
||||
}
|
||||
|
||||
// NIP-XX BOLT12 zaps — count only the crypto-verified ones. An unverified
|
||||
// NIP-B1 BOLT12 zaps — count only the crypto-verified ones. An unverified
|
||||
// (compressed, or offer-unbindable) proof carries a self-chosen preimage,
|
||||
// amount, and payment hash with no settled-payment guarantee, so counting it
|
||||
// would let anyone inflate a note's total for free. Unverified entries stay
|
||||
|
||||
+1
-1
@@ -30,8 +30,8 @@ import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
|
||||
import com.vitorpamplona.quartz.nip25Reactions.ReactionEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.nutzap.NutzapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.collections.immutable.toImmutableSet
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ import com.vitorpamplona.quartz.nip19Bech32.toNpub
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.info.NutzapInfoEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.info.tags.NutzapMintTag
|
||||
import com.vitorpamplona.quartz.nip65RelayList.AdvertisedRelayListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlin.concurrent.Volatile
|
||||
|
||||
@@ -116,7 +116,7 @@ class User(
|
||||
|
||||
fun nutzapInfo() = nutzapInfoNote.event as? NutzapInfoEvent
|
||||
|
||||
/** This user's published BOLT12 offer list (NIP-XX kind 10058), or null if none seen. */
|
||||
/** This user's published BOLT12 offer list (NIP-B1 kind 10058), or null if none seen. */
|
||||
fun bolt12OfferList() = bolt12OfferListNote.event as? Bolt12OfferListEvent
|
||||
|
||||
/** The canonical raw BOLT12 offers (`lno1...`) this user accepts, empty when none published. */
|
||||
|
||||
+2
-2
@@ -35,8 +35,8 @@ import com.vitorpamplona.quartz.nip28PublicChat.message.ChannelMessageEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip59Giftwrap.wraps.GiftWrapEvent
|
||||
import com.vitorpamplona.quartz.nip61Nutzaps.nutzap.NutzapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
/**
|
||||
* Nostr event kinds that can generate a notification when they tag the
|
||||
@@ -71,7 +71,7 @@ object NotificationKinds {
|
||||
NutzapEvent.KIND, // 9321 — NIP-61 Cashu nutzap
|
||||
LnZapEvent.KIND, // 9735 — NIP-57 zap receipt
|
||||
OnchainZapEvent.KIND, // 8333 — onchain zap
|
||||
Bolt12ZapEvent.KIND, // 9736 — NIP-XX BOLT12 zap
|
||||
Bolt12ZapEvent.KIND, // 9736 — NIP-B1 BOLT12 zap
|
||||
// NIP-17 file-header messages (encrypted file DMs)
|
||||
ChatMessageEncryptedFileHeaderEvent.KIND,
|
||||
)
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ import com.vitorpamplona.amethyst.commons.nip53LiveActivities.ZapContribution
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapRequestEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.IO
|
||||
import kotlinx.coroutines.Job
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ package com.vitorpamplona.amethyst.commons.viewmodels
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip57Zaps.LnZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
|
||||
/**
|
||||
* One in-flight kind-9735 zap to render as a floating overlay on the
|
||||
|
||||
+5
-5
@@ -22,11 +22,11 @@ package com.vitorpamplona.amethyst.commons.actions
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Values
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.TlvRecord
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.TlvStream
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Values
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.TlvRecord
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.TlvStream
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Verifies how validated NIP-XX BOLT12 zaps fold into a Note's aggregate zap
|
||||
* Verifies how validated NIP-B1 BOLT12 zaps fold into a Note's aggregate zap
|
||||
* accounting — the model contract the LocalCache ingest path and the reaction-row
|
||||
* counter depend on.
|
||||
*/
|
||||
@@ -57,7 +57,7 @@ class NoteBolt12ZapTest {
|
||||
|
||||
@Test
|
||||
fun keepsTheLowerAmountWhenTwoProofsShareAPaymentHash() {
|
||||
// NIP-XX: same proof identifier, differing amounts → count the LOWER, in either order.
|
||||
// NIP-B1: same proof identifier, differing amounts → count the LOWER, in either order.
|
||||
val a = note("a".repeat(64))
|
||||
a.addBolt12Zap(note("b".repeat(64)), "h", amountMillisats = 21_000_000L, cryptoVerified = true)
|
||||
a.addBolt12Zap(note("c".repeat(64)), "h", amountMillisats = 5_000_000L, cryptoVerified = true)
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ import com.vitorpamplona.nestsclient.connectReconnectingNestsSpeaker
|
||||
import com.vitorpamplona.nestsclient.transport.WebTransportFactory
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip53LiveActivities.chat.LiveActivitiesChatMessageEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import kotlinx.collections.immutable.ImmutableSet
|
||||
import kotlinx.collections.immutable.persistentSetOf
|
||||
|
||||
@@ -294,6 +294,8 @@ import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallOfferEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRejectEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRenegotiateEvent
|
||||
import com.vitorpamplona.quartz.nipB0WebBookmarks.WebBookmarkEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomAuthorizationEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomServersEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
@@ -303,8 +305,6 @@ import com.vitorpamplona.quartz.nipF4Podcasts.authored.AuthoredPodcastsEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.favorites.FavoritePodcastsListEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.episode.Podcasting20EpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.trailer.Podcasting20TrailerEvent
|
||||
|
||||
@@ -541,8 +541,8 @@ object KindNames {
|
||||
RelayAddMemberEvent.KIND to KindName("Relay Add Member", "43"),
|
||||
RelayRemoveMemberEvent.KIND to KindName("Relay Remove Member", "43"),
|
||||
OnchainZapEvent.KIND to KindName("Onchain Zap", "BC"),
|
||||
Bolt12ZapEvent.KIND to KindName("Bolt12 Zap", "XX"),
|
||||
Bolt12OfferListEvent.KIND to KindName("Bolt12 Offers", "XX"),
|
||||
Bolt12ZapEvent.KIND to KindName("Bolt12 Zap", "B1"),
|
||||
Bolt12OfferListEvent.KIND to KindName("Bolt12 Offers", "B1"),
|
||||
PutUserEvent.KIND to KindName("Group Put User", "29"),
|
||||
RemoveUserEvent.KIND to KindName("Group Remove User", "29"),
|
||||
EditMetadataEvent.KIND to KindName("Group Edit Metadata", "29"),
|
||||
|
||||
+1
-1
@@ -51,7 +51,7 @@ class PayInvoiceMethod(
|
||||
// (bolt11 `lightning=`, BOLT12 `lno=`, or on-chain). `payment` is the BIP321 URI;
|
||||
// `amount` (msats) is required only when the instruction has no amount; `payer_note`
|
||||
// is delivered to the payee when the instruction supports payer messages (for a
|
||||
// BOLT12 zap this carries `nostr:nipXX:<intent-id>`).
|
||||
// BOLT12 zap this carries `nostr:nipB1:<intent-id>`).
|
||||
class PayParams(
|
||||
var payment: String? = null,
|
||||
var amount: Long? = null,
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
import com.vitorpamplona.quartz.nip19Bech32.bech32.Bech32
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||
|
||||
+2
-2
@@ -18,10 +18,10 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
/**
|
||||
* A parsed BOLT12 offer (`lno1...`). Exposes the fields NIP-XX cares about; the
|
||||
* A parsed BOLT12 offer (`lno1...`). Exposes the fields NIP-B1 cares about; the
|
||||
* full TLV stream is retained for callers that need more.
|
||||
*
|
||||
* See https://github.com/lightning/bolts/blob/master/12-offer-encoding.md#offer-fields
|
||||
+2
-2
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
/**
|
||||
* A parsed BOLT12 payer proof (`lnp1...`), per lightning/bolts#1346.
|
||||
@@ -108,7 +108,7 @@ class Bolt12PayerProof(
|
||||
/**
|
||||
* True when every field the BOLT12 crypto verification requires is present and
|
||||
* well-sized (lightning/bolts#1346 reader rules). `invreq_payer_note` is *not*
|
||||
* required here — the NIP-XX zap binding checks it separately in the validator.
|
||||
* required here — the NIP-B1 zap binding checks it separately in the validator.
|
||||
*/
|
||||
fun hasAllCryptoFields(): Boolean =
|
||||
invreqPayerId() != null &&
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
/**
|
||||
* Mints a canonical BOLT12 `lnp1...` payer proof from a full invoice, per
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
/**
|
||||
* BOLT-1 BigSize codec: a variable-length unsigned integer, big-endian, with a
|
||||
+5
-5
@@ -18,21 +18,21 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.builder
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.builder
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidator
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidator
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import com.vitorpamplona.quartz.utils.RandomInstance
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
/**
|
||||
* Assembles the two NIP-XX events in the order the payment flow requires:
|
||||
* Assembles the two NIP-B1 events in the order the payment flow requires:
|
||||
*
|
||||
* 1. [buildIntent] — sign a kind 9737 zap intent *before* paying.
|
||||
* 2. Pay the offer, putting [payerNote] in the BOLT12 `invreq_payer_note`, and
|
||||
+6
-6
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.intent
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.AddressableEvent
|
||||
@@ -36,18 +36,18 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.toETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.ZapIdTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.ZapIdTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
/**
|
||||
* NIP-XX: BOLT12 Zaps — the **zap intent** (kind 9737).
|
||||
* NIP-B1: BOLT12 Zaps — the **zap intent** (kind 9737).
|
||||
*
|
||||
* The payer creates and signs this event *before* paying the BOLT12 offer. It
|
||||
* binds the payer's Nostr key to the recipient, the target, the amount and the
|
||||
* offer. The payer then references this event's id in the BOLT12
|
||||
* `invreq_payer_note` (`nostr:nipXX:<zap-intent-event-id>`), and finally embeds
|
||||
* `invreq_payer_note` (`nostr:nipB1:<zap-intent-event-id>`), and finally embeds
|
||||
* the whole serialized intent inside the kind 9736 zap event's `description` tag
|
||||
* — the same embedding pattern NIP-57 uses for the zap request.
|
||||
*
|
||||
+4
-4
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.intent
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
@@ -26,9 +26,9 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.ZapIdTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.ZapIdTag
|
||||
|
||||
fun TagArrayBuilder<Bolt12ZapIntentEvent>.recipient(recipientPubKey: HexKey) = addUnique(PTag.assemble(recipientPubKey, null))
|
||||
|
||||
+3
-3
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.offer
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Address
|
||||
@@ -27,11 +27,11 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerSync
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
/**
|
||||
* NIP-XX: BOLT12 Zaps — a user's **BOLT12 offer list** (kind 10058).
|
||||
* NIP-B1: BOLT12 Zaps — a user's **BOLT12 offer list** (kind 10058).
|
||||
*
|
||||
* A replaceable event, anchored to the author's pubkey, that publishes one or more
|
||||
* canonical raw BOLT12 offers (`["offer", "lno1..."]`). This is how a payer
|
||||
+2
-2
@@ -18,13 +18,13 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.tags
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
/**
|
||||
* The `amount` tag of a NIP-XX BOLT12 zap or zap intent: the payment amount in
|
||||
* The `amount` tag of a NIP-B1 BOLT12 zap or zap intent: the payment amount in
|
||||
* **millisatoshis** (not sats — this matches the BOLT12 `invoice_amount` field it
|
||||
* is validated against, and NIP-57's `amount` tag).
|
||||
*/
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.tags
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
+2
-2
@@ -18,10 +18,10 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.tags
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
/**
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.tags
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
+2
-2
@@ -18,10 +18,10 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.tags
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.utils.ensure
|
||||
|
||||
/**
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.tags
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.has
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.verify
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
+4
-4
@@ -18,12 +18,12 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.verify
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Merkle
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.TlvRecord
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Merkle
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.TlvRecord
|
||||
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||
|
||||
/**
|
||||
+2
-2
@@ -18,12 +18,12 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.verify
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
|
||||
/** Result of validating a NIP-XX BOLT12 zap event (kind 9736). */
|
||||
/** Result of validating a NIP-B1 BOLT12 zap event (kind 9736). */
|
||||
@Immutable
|
||||
sealed interface Bolt12ZapValidation {
|
||||
/**
|
||||
+9
-9
@@ -18,20 +18,20 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.verify
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.verify
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.DescriptionTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.DescriptionTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
|
||||
/**
|
||||
* NIP-XX validator: runs the spec's validation steps over a [Bolt12ZapEvent] and
|
||||
* NIP-B1 validator: runs the spec's validation steps over a [Bolt12ZapEvent] and
|
||||
* returns a [Bolt12ZapValidation]. A client MUST validate an event with this (and
|
||||
* deduplicate the results by [Bolt12ZapValidation.Valid.paymentHashHex]) before
|
||||
* counting a BOLT12 zap.
|
||||
@@ -47,7 +47,7 @@ import com.vitorpamplona.quartz.utils.Hex
|
||||
* 5. the raw BOLT12 offer parses;
|
||||
* 6. the `lnp` payer proof decodes and its crypto checks pass (see
|
||||
* [Bolt12ProofVerifier]);
|
||||
* 7. the proof binds to this zap: `invreq_payer_note == nostr:nipXX:<intent-id>`,
|
||||
* 7. the proof binds to this zap: `invreq_payer_note == nostr:nipB1:<intent-id>`,
|
||||
* `invoice_amount == amount`, and the proof matches the offer.
|
||||
*/
|
||||
class Bolt12ZapValidator(
|
||||
@@ -236,9 +236,9 @@ class Bolt12ZapValidator(
|
||||
/**
|
||||
* The NIP binds the Lightning payment to the signed intent through the
|
||||
* BOLT12 `invreq_payer_note`, which MUST equal this prefix followed by the
|
||||
* intent event id. The `nipXX` segment tracks the final NIP number.
|
||||
* intent event id. The `nipB1` segment is the assigned NIP-B1 number.
|
||||
*/
|
||||
const val NIP_URI_PREFIX = "nostr:nipXX:"
|
||||
const val NIP_URI_PREFIX = "nostr:nipB1:"
|
||||
}
|
||||
}
|
||||
|
||||
+8
-8
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.zap
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
@@ -34,17 +34,17 @@ import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nip50Search.SearchableEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.DescriptionTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.PayerTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.ProofTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.DescriptionTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.PayerTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.ProofTag
|
||||
import com.vitorpamplona.quartz.utils.Log
|
||||
import com.vitorpamplona.quartz.utils.TimeUtils
|
||||
|
||||
/**
|
||||
* NIP-XX: BOLT12 Zaps — the **zap event** (kind 9736).
|
||||
* NIP-B1: BOLT12 Zaps — the **zap event** (kind 9736).
|
||||
*
|
||||
* A public, self-verifying proof that a BOLT12 payment was made to the author of
|
||||
* a profile, event, or addressable event. It carries:
|
||||
+6
-6
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.zap
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||
import com.vitorpamplona.quartz.nip01Core.core.TagArrayBuilder
|
||||
@@ -26,11 +26,11 @@ import com.vitorpamplona.quartz.nip01Core.tags.aTag.ATag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.events.ETag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.kinds.KindTag
|
||||
import com.vitorpamplona.quartz.nip01Core.tags.people.PTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.DescriptionTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.PayerTag
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.tags.ProofTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.AmountTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.DescriptionTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.OfferTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.PayerTag
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.tags.ProofTag
|
||||
|
||||
fun TagArrayBuilder<Bolt12ZapEvent>.description(serializedIntentEventJson: String) = addUnique(DescriptionTag.assemble(serializedIntentEventJson))
|
||||
|
||||
@@ -386,6 +386,9 @@ import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallOfferEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRejectEvent
|
||||
import com.vitorpamplona.quartz.nipACWebRtcCalls.events.CallRenegotiateEvent
|
||||
import com.vitorpamplona.quartz.nipB0WebBookmarks.WebBookmarkEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomAuthorizationEvent
|
||||
import com.vitorpamplona.quartz.nipB7Blossom.BlossomServersEvent
|
||||
import com.vitorpamplona.quartz.nipBCOnchainZaps.zap.OnchainZapEvent
|
||||
@@ -395,9 +398,6 @@ import com.vitorpamplona.quartz.nipF4Podcasts.authored.AuthoredPodcastsEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.episode.PodcastEpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.favorites.FavoritePodcastsListEvent
|
||||
import com.vitorpamplona.quartz.nipF4Podcasts.metadata.PodcastMetadataEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.offer.Bolt12OfferListEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.episode.Podcasting20EpisodeEvent
|
||||
import com.vitorpamplona.quartz.nipXXPodcasting20.trailer.Podcasting20TrailerEvent
|
||||
|
||||
|
||||
+6
-6
@@ -95,31 +95,31 @@ class RequestTest {
|
||||
|
||||
@Test
|
||||
fun testPayCreateWithOfferAndPayerNote() {
|
||||
val request = PayMethod.create("bitcoin:?lno=lno1abc", amount = 21_000L, payerNote = "nostr:nipXX:deadbeef")
|
||||
val request = PayMethod.create("bitcoin:?lno=lno1abc", amount = 21_000L, payerNote = "nostr:nipB1:deadbeef")
|
||||
assertEquals(NwcMethod.PAY, request.method)
|
||||
assertEquals("bitcoin:?lno=lno1abc", request.params?.payment)
|
||||
assertEquals(21_000L, request.params?.amount)
|
||||
assertEquals("nostr:nipXX:deadbeef", request.params?.payer_note)
|
||||
assertEquals("nostr:nipB1:deadbeef", request.params?.payer_note)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPaySerialization() {
|
||||
val request = PayMethod.create("bitcoin:?lno=lno1abc", amount = 21_000L, payerNote = "nostr:nipXX:deadbeef")
|
||||
val request = PayMethod.create("bitcoin:?lno=lno1abc", amount = 21_000L, payerNote = "nostr:nipB1:deadbeef")
|
||||
val json = OptimizedJsonMapper.toJson(request)
|
||||
assertTrue(json.contains("\"method\":\"pay\""))
|
||||
assertTrue(json.contains("\"payment\":\"bitcoin:?lno=lno1abc\""))
|
||||
assertTrue(json.contains("\"amount\":21000"))
|
||||
assertTrue(json.contains("\"payer_note\":\"nostr:nipXX:deadbeef\""))
|
||||
assertTrue(json.contains("\"payer_note\":\"nostr:nipB1:deadbeef\""))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPayDeserialization() {
|
||||
val json = """{"method":"pay","params":{"payment":"bitcoin:?lno=lno1abc","amount":21000,"payer_note":"nostr:nipXX:deadbeef"}}"""
|
||||
val json = """{"method":"pay","params":{"payment":"bitcoin:?lno=lno1abc","amount":21000,"payer_note":"nostr:nipB1:deadbeef"}}"""
|
||||
val request = OptimizedJsonMapper.fromJsonTo<Request>(json)
|
||||
assertIs<PayMethod>(request)
|
||||
assertEquals("bitcoin:?lno=lno1abc", request.params?.payment)
|
||||
assertEquals(21_000L, request.params?.amount)
|
||||
assertEquals("nostr:nipXX:deadbeef", request.params?.payer_note)
|
||||
assertEquals("nostr:nipB1:deadbeef", request.params?.payer_note)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+4
-4
@@ -18,15 +18,15 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.hints.EventHintBundle
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertContentEquals
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12
|
||||
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlin.test.Test
|
||||
+4
-4
@@ -18,13 +18,13 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.builder
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.builder
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ProofFixture
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.verify.Bolt12ZapValidator
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ProofFixture
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidation
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify.Bolt12ZapValidator
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
+2
-2
@@ -18,12 +18,12 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.offer
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.offer
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.core.Event
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
+3
-3
@@ -18,11 +18,11 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.verify
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify
|
||||
|
||||
import com.vitorpamplona.quartz.TestResourceLoader
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12ProofBuilder
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12ProofBuilder
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
+8
-8
@@ -18,17 +18,17 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.verify
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12ProofBuilder
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.Bolt12Values
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.TlvRecord
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.bolt12.TlvStream
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Bech32
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Offer
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12PayerProof
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12ProofBuilder
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.Bolt12Values
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.TlvRecord
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.bolt12.TlvStream
|
||||
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||
|
||||
/**
|
||||
+3
-3
@@ -18,13 +18,13 @@
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
package com.vitorpamplona.quartz.nipXXBolt12Zaps.verify
|
||||
package com.vitorpamplona.quartz.nipB1Bolt12Zaps.verify
|
||||
|
||||
import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSigner
|
||||
import com.vitorpamplona.quartz.nip01Core.signers.NostrSignerInternal
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipXXBolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.intent.Bolt12ZapIntentEvent
|
||||
import com.vitorpamplona.quartz.nipB1Bolt12Zaps.zap.Bolt12ZapEvent
|
||||
import com.vitorpamplona.quartz.utils.Hex
|
||||
import com.vitorpamplona.quartz.utils.sha256.sha256
|
||||
import kotlinx.coroutines.test.runTest
|
||||
Reference in New Issue
Block a user