nip61: perhaps simplify the function signature and support specific source mints.
This commit is contained in:
@@ -16,21 +16,34 @@ import (
|
|||||||
|
|
||||||
var NutzapsNotAccepted = errors.New("user doesn't accept nutzaps")
|
var NutzapsNotAccepted = errors.New("user doesn't accept nutzaps")
|
||||||
|
|
||||||
|
type NutzapOptions struct {
|
||||||
|
// Optionally specify the event we'll reference in the nutzap,
|
||||||
|
// if not specified we'll just send money to the receiver
|
||||||
|
EventID nostr.ID
|
||||||
|
|
||||||
|
// string message to include in the nutzap
|
||||||
|
Message string
|
||||||
|
|
||||||
|
// We'll send the nutzap to these relays besides any relay found in the kind:10019
|
||||||
|
SendToRelays []string
|
||||||
|
|
||||||
|
// Send specifically from this mint
|
||||||
|
SpecificSourceMint string
|
||||||
|
}
|
||||||
|
|
||||||
func SendNutzap(
|
func SendNutzap(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
kr nostr.Keyer,
|
kr nostr.Keyer,
|
||||||
w *nip60.Wallet,
|
w *nip60.Wallet,
|
||||||
pool *nostr.Pool,
|
pool *nostr.Pool,
|
||||||
targetUserPublickey nostr.PubKey,
|
|
||||||
getUserReadRelays func(context.Context, nostr.PubKey, int) []string,
|
|
||||||
relays []string,
|
|
||||||
eventId nostr.ID, // can be "" if not targeting a specific event
|
|
||||||
amount uint64,
|
amount uint64,
|
||||||
message string,
|
targetUser nostr.PubKey,
|
||||||
|
targetUserRelays []string,
|
||||||
|
opts NutzapOptions,
|
||||||
) (chan nostr.PublishResult, error) {
|
) (chan nostr.PublishResult, error) {
|
||||||
ie := pool.QuerySingle(ctx, relays, nostr.Filter{
|
ie := pool.QuerySingle(ctx, targetUserRelays, nostr.Filter{
|
||||||
Kinds: []nostr.Kind{10019},
|
Kinds: []nostr.Kind{10019},
|
||||||
Authors: []nostr.PubKey{targetUserPublickey},
|
Authors: []nostr.PubKey{targetUser},
|
||||||
},
|
},
|
||||||
nostr.SubscriptionOptions{Label: "pre-nutzap"})
|
nostr.SubscriptionOptions{Label: "pre-nutzap"})
|
||||||
if ie == nil {
|
if ie == nil {
|
||||||
@@ -46,13 +59,10 @@ func SendNutzap(
|
|||||||
return nil, NutzapsNotAccepted
|
return nil, NutzapsNotAccepted
|
||||||
}
|
}
|
||||||
|
|
||||||
targetRelays := info.Relays
|
targetRelays := nostr.AppendUnique(info.Relays, opts.SendToRelays...)
|
||||||
if len(targetRelays) == 0 {
|
|
||||||
targetRelays = getUserReadRelays(ctx, targetUserPublickey, 3)
|
|
||||||
if len(targetRelays) == 0 {
|
if len(targetRelays) == 0 {
|
||||||
return nil, fmt.Errorf("no relays found for sending the nutzap")
|
return nil, fmt.Errorf("no relays found for sending the nutzap")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nutzap := nostr.Event{
|
nutzap := nostr.Event{
|
||||||
CreatedAt: nostr.Now(),
|
CreatedAt: nostr.Now(),
|
||||||
@@ -60,9 +70,9 @@ func SendNutzap(
|
|||||||
Tags: make(nostr.Tags, 0, 8),
|
Tags: make(nostr.Tags, 0, 8),
|
||||||
}
|
}
|
||||||
|
|
||||||
nutzap.Tags = append(nutzap.Tags, nostr.Tag{"p", targetUserPublickey.Hex()})
|
nutzap.Tags = append(nutzap.Tags, nostr.Tag{"p", targetUser.Hex()})
|
||||||
if eventId != nostr.ZeroID {
|
if opts.EventID != nostr.ZeroID {
|
||||||
nutzap.Tags = append(nutzap.Tags, nostr.Tag{"e", eventId.Hex()})
|
nutzap.Tags = append(nutzap.Tags, nostr.Tag{"e", opts.EventID.Hex()})
|
||||||
}
|
}
|
||||||
|
|
||||||
p2pk, err := btcec.ParsePubKey(append([]byte{2}, info.PublicKey[:]...))
|
p2pk, err := btcec.ParsePubKey(append([]byte{2}, info.PublicKey[:]...))
|
||||||
@@ -72,6 +82,10 @@ func SendNutzap(
|
|||||||
|
|
||||||
// check if we have enough tokens in any of these mints
|
// check if we have enough tokens in any of these mints
|
||||||
for mint := range getEligibleTokensWeHave(info.Mints, w.Tokens, amount) {
|
for mint := range getEligibleTokensWeHave(info.Mints, w.Tokens, amount) {
|
||||||
|
if opts.SpecificSourceMint != "" && opts.SpecificSourceMint != mint {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
proofs, _, err := w.Send(ctx, amount, nip60.SendOptions{
|
proofs, _, err := w.Send(ctx, amount, nip60.SendOptions{
|
||||||
P2PK: p2pk,
|
P2PK: p2pk,
|
||||||
SpecificSourceMint: mint,
|
SpecificSourceMint: mint,
|
||||||
@@ -98,6 +112,7 @@ func SendNutzap(
|
|||||||
for _, mint := range info.Mints {
|
for _, mint := range info.Mints {
|
||||||
proofs, err := w.SendExternal(ctx, mint, amount, nip60.SendOptions{
|
proofs, err := w.SendExternal(ctx, mint, amount, nip60.SendOptions{
|
||||||
P2PK: p2pk,
|
P2PK: p2pk,
|
||||||
|
SpecificSourceMint: opts.SpecificSourceMint,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "generate mint quote") {
|
if strings.Contains(err.Error(), "generate mint quote") {
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
package sdk
|
|
||||||
|
|
||||||
import (
|
|
||||||
"slices"
|
|
||||||
|
|
||||||
jsoniter "github.com/json-iterator/go"
|
|
||||||
)
|
|
||||||
|
|
||||||
var json = jsoniter.ConfigFastest
|
|
||||||
|
|
||||||
// appendUnique adds items to an array only if they don't already exist in the array.
|
|
||||||
// Returns the modified array.
|
|
||||||
func appendUnique[I comparable](arr []I, item ...I) []I {
|
|
||||||
for _, item := range item {
|
|
||||||
if slices.Contains(arr, item) {
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
arr = append(arr, item)
|
|
||||||
}
|
|
||||||
return arr
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@ package sdk
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ func (sys *System) FetchSpecificEvent(
|
|||||||
author = v.Author
|
author = v.Author
|
||||||
filter.IDs = []nostr.ID{v.ID}
|
filter.IDs = []nostr.ID{v.ID}
|
||||||
relays = append(relays, v.Relays...)
|
relays = append(relays, v.Relays...)
|
||||||
relays = appendUnique(relays, sys.FallbackRelays.Next())
|
relays = nostr.AppendUnique(relays, sys.FallbackRelays.Next())
|
||||||
fallback = append(fallback, sys.JustIDRelays.URLs...)
|
fallback = append(fallback, sys.JustIDRelays.URLs...)
|
||||||
fallback = appendUnique(fallback, sys.FallbackRelays.Next())
|
fallback = nostr.AppendUnique(fallback, sys.FallbackRelays.Next())
|
||||||
priorityRelays = append(priorityRelays, v.Relays...)
|
priorityRelays = append(priorityRelays, v.Relays...)
|
||||||
case nostr.EntityPointer:
|
case nostr.EntityPointer:
|
||||||
author = v.PublicKey
|
author = v.PublicKey
|
||||||
@@ -86,7 +86,7 @@ func (sys *System) FetchSpecificEvent(
|
|||||||
filter.Tags = nostr.TagMap{"d": []string{v.Identifier}}
|
filter.Tags = nostr.TagMap{"d": []string{v.Identifier}}
|
||||||
filter.Kinds = []nostr.Kind{v.Kind}
|
filter.Kinds = []nostr.Kind{v.Kind}
|
||||||
relays = append(relays, v.Relays...)
|
relays = append(relays, v.Relays...)
|
||||||
relays = appendUnique(relays, sys.FallbackRelays.Next())
|
relays = nostr.AppendUnique(relays, sys.FallbackRelays.Next())
|
||||||
fallback = append(fallback, sys.FallbackRelays.Next(), sys.FallbackRelays.Next())
|
fallback = append(fallback, sys.FallbackRelays.Next(), sys.FallbackRelays.Next())
|
||||||
priorityRelays = append(priorityRelays, v.Relays...)
|
priorityRelays = append(priorityRelays, v.Relays...)
|
||||||
}
|
}
|
||||||
@@ -110,8 +110,8 @@ func (sys *System) FetchSpecificEvent(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// arrange these
|
// arrange these
|
||||||
relays = appendUnique(relays, authorRelays...)
|
relays = nostr.AppendUnique(relays, authorRelays...)
|
||||||
priorityRelays = appendUnique(priorityRelays, authorRelays...)
|
priorityRelays = nostr.AppendUnique(priorityRelays, authorRelays...)
|
||||||
}
|
}
|
||||||
|
|
||||||
var result *nostr.Event
|
var result *nostr.Event
|
||||||
|
|||||||
13
utils.go
13
utils.go
@@ -5,6 +5,7 @@ import (
|
|||||||
"cmp"
|
"cmp"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsValidRelayURL checks if a URL is a valid relay URL (ws:// or wss://).
|
// IsValidRelayURL checks if a URL is a valid relay URL (ws:// or wss://).
|
||||||
@@ -46,3 +47,15 @@ func CompareEventReverse(b, a Event) int {
|
|||||||
}
|
}
|
||||||
return cmp.Compare(a.CreatedAt, b.CreatedAt)
|
return cmp.Compare(a.CreatedAt, b.CreatedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AppendUnique adds items to an array only if they don't already exist in the array.
|
||||||
|
// Returns the modified array.
|
||||||
|
func AppendUnique[I comparable](arr []I, item ...I) []I {
|
||||||
|
for _, item := range item {
|
||||||
|
if slices.Contains(arr, item) {
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
arr = append(arr, item)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user