mirror of
https://github.com/fiatjaf/nak.git
synced 2026-10-05 15:18:23 +00:00
nsite: accept naddr/nevent, support napps/napplets, take optional --server flag.
This commit is contained in:
@@ -3,7 +3,7 @@ module github.com/fiatjaf/nak
|
|||||||
go 1.25
|
go 1.25
|
||||||
|
|
||||||
require (
|
require (
|
||||||
fiatjaf.com/nostr v0.0.0-20260919022302-cf8167ebdb95
|
fiatjaf.com/nostr v0.0.0-20260928115942-58e4c715304e
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
github.com/bep/debounce v1.2.1
|
github.com/bep/debounce v1.2.1
|
||||||
github.com/btcsuite/btcd/btcec/v2 v2.3.6
|
github.com/btcsuite/btcd/btcec/v2 v2.3.6
|
||||||
|
|||||||
@@ -1,15 +1,7 @@
|
|||||||
fiatjaf.com/lib v0.3.7 h1:mXZOn7NrUcjSdy4oNvwQyAmes7Ueb+Zr5hjqMIe2dxI=
|
fiatjaf.com/lib v0.3.7 h1:mXZOn7NrUcjSdy4oNvwQyAmes7Ueb+Zr5hjqMIe2dxI=
|
||||||
fiatjaf.com/lib v0.3.7/go.mod h1:UlHaZvPHj25PtKLh9GjZkUHRmQ2xZ8Jkoa4VRaLeeQ8=
|
fiatjaf.com/lib v0.3.7/go.mod h1:UlHaZvPHj25PtKLh9GjZkUHRmQ2xZ8Jkoa4VRaLeeQ8=
|
||||||
fiatjaf.com/nostr v0.0.0-20260827104008-28e324b57f7e h1:BuWR1BP/CBzM+ZbLoUKuV6KlktlDZEyD9N/pdxqJJyE=
|
fiatjaf.com/nostr v0.0.0-20260928115942-58e4c715304e h1:ZHPQsQzd0rGdOq/vCMUOy9FfrzlmAxvQ+V+4ucJ1WXY=
|
||||||
fiatjaf.com/nostr v0.0.0-20260827104008-28e324b57f7e/go.mod h1:b1EIUDnd133Ie8Pg8O/biaKdFyCMz28aD4n64g1GqvM=
|
fiatjaf.com/nostr v0.0.0-20260928115942-58e4c715304e/go.mod h1:b1EIUDnd133Ie8Pg8O/biaKdFyCMz28aD4n64g1GqvM=
|
||||||
fiatjaf.com/nostr v0.0.0-20260914174524-1ce6fccff3c3 h1:xzGlJR7EupVzxD5XGP/y4Z/i5qAxaBH3TzvCPyemLZM=
|
|
||||||
fiatjaf.com/nostr v0.0.0-20260914174524-1ce6fccff3c3/go.mod h1:b1EIUDnd133Ie8Pg8O/biaKdFyCMz28aD4n64g1GqvM=
|
|
||||||
fiatjaf.com/nostr v0.0.0-20260916003959-33dfb12f7374 h1:Ms85MGJyOpKsG6y4llGwa/9ro3OtZBcmdXtJwOa/Qg4=
|
|
||||||
fiatjaf.com/nostr v0.0.0-20260916003959-33dfb12f7374/go.mod h1:b1EIUDnd133Ie8Pg8O/biaKdFyCMz28aD4n64g1GqvM=
|
|
||||||
fiatjaf.com/nostr v0.0.0-20260916040958-27e395a0f6e7 h1:UKC6fhAmyoDQTQ7FH6gTF31WSprVgLYUiLiV8BRPEbU=
|
|
||||||
fiatjaf.com/nostr v0.0.0-20260916040958-27e395a0f6e7/go.mod h1:b1EIUDnd133Ie8Pg8O/biaKdFyCMz28aD4n64g1GqvM=
|
|
||||||
fiatjaf.com/nostr v0.0.0-20260919022302-cf8167ebdb95 h1:E59biPECxSHqdfjGFwQ+UMoZSnZfK9tjrpXuLVes6gY=
|
|
||||||
fiatjaf.com/nostr v0.0.0-20260919022302-cf8167ebdb95/go.mod h1:b1EIUDnd133Ie8Pg8O/biaKdFyCMz28aD4n64g1GqvM=
|
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
|
||||||
github.com/FastFilter/xorfilter v0.2.1 h1:lbdeLG9BdpquK64ZsleBS8B4xO/QW1IM0gMzF7KaBKc=
|
github.com/FastFilter/xorfilter v0.2.1 h1:lbdeLG9BdpquK64ZsleBS8B4xO/QW1IM0gMzF7KaBKc=
|
||||||
|
|||||||
@@ -246,6 +246,13 @@ var nsite = &cli.Command{
|
|||||||
Usage: "downloads all files from a published nsite",
|
Usage: "downloads all files from a published nsite",
|
||||||
ArgsUsage: "<site> [directory]",
|
ArgsUsage: "<site> [directory]",
|
||||||
DisableSliceFlagSeparator: true,
|
DisableSliceFlagSeparator: true,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringSliceFlag{
|
||||||
|
Name: "server",
|
||||||
|
Aliases: []string{"s"},
|
||||||
|
Usage: "extra blossom server hostname or URL to try, can be given multiple times",
|
||||||
|
},
|
||||||
|
},
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
input := c.Args().First()
|
input := c.Args().First()
|
||||||
if input == "" {
|
if input == "" {
|
||||||
@@ -265,23 +272,45 @@ var nsite = &cli.Command{
|
|||||||
return fmt.Errorf("failed to stat output directory %s: %w", outputDir, err)
|
return fmt.Errorf("failed to stat output directory %s: %w", outputDir, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
pk, identifier, isRoot, err := nip5a.DecodeSiteURL(input)
|
var filter nostr.Filter
|
||||||
if err != nil {
|
var relays []string
|
||||||
|
var readOnlySigner nostr.Signer = keyer.NewReadOnlySigner(nostr.ZeroPK)
|
||||||
|
|
||||||
|
if strings.HasPrefix(input, "nostr:") {
|
||||||
|
input = input[6:]
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(input, "nevent1") || strings.HasPrefix(input, "naddr1") {
|
||||||
|
ptr, err := nip19.ToPointer(input)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
filter = ptr.AsFilter()
|
||||||
|
|
||||||
|
if pk := ptr.AssociatedPublicKey(); pk != nostr.ZeroPK {
|
||||||
|
relays = sys.FetchWriteRelays(ctx, pk)
|
||||||
|
readOnlySigner = keyer.NewReadOnlySigner(pk)
|
||||||
|
}
|
||||||
|
relays = append(relays, ptr.RelayHints()...)
|
||||||
|
} else if pk, identifier, isRoot, err := nip5a.DecodeSiteURL(input); err == nil {
|
||||||
|
filter = nostr.Filter{
|
||||||
|
Authors: []nostr.PubKey{pk},
|
||||||
|
Limit: 1,
|
||||||
|
}
|
||||||
|
if isRoot {
|
||||||
|
filter.Kinds = []nostr.Kind{nostr.KindNsiteRoot}
|
||||||
|
} else {
|
||||||
|
filter.Kinds = []nostr.Kind{nostr.KindNsiteNamed}
|
||||||
|
filter.Tags = nostr.TagMap{"d": []string{identifier}}
|
||||||
|
}
|
||||||
|
|
||||||
|
relays = sys.FetchWriteRelays(ctx, pk)
|
||||||
|
readOnlySigner = keyer.NewReadOnlySigner(pk)
|
||||||
|
} else {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
filter := nostr.Filter{
|
res := sys.Pool.QuerySingle(ctx, relays, filter, nostr.SubscriptionOptions{
|
||||||
Authors: []nostr.PubKey{pk},
|
|
||||||
Limit: 1,
|
|
||||||
}
|
|
||||||
if isRoot {
|
|
||||||
filter.Kinds = []nostr.Kind{nostr.KindNsiteRoot}
|
|
||||||
} else {
|
|
||||||
filter.Kinds = []nostr.Kind{nostr.KindNsiteNamed}
|
|
||||||
filter.Tags = nostr.TagMap{"d": []string{identifier}}
|
|
||||||
}
|
|
||||||
|
|
||||||
res := sys.Pool.QuerySingle(ctx, sys.FetchWriteRelays(ctx, pk), filter, nostr.SubscriptionOptions{
|
|
||||||
Label: "nak-nsite",
|
Label: "nak-nsite",
|
||||||
})
|
})
|
||||||
if res == nil {
|
if res == nil {
|
||||||
@@ -297,15 +326,18 @@ var nsite = &cli.Command{
|
|||||||
if len(blossomServers) == 0 {
|
if len(blossomServers) == 0 {
|
||||||
servers := sys.FetchBlossomServerList(ctx, res.Event.PubKey)
|
servers := sys.FetchBlossomServerList(ctx, res.Event.PubKey)
|
||||||
if len(servers.Items) == 0 {
|
if len(servers.Items) == 0 {
|
||||||
return fmt.Errorf("no blossom servers advertised in manifest or kind:10063")
|
blossomServers = []string{}
|
||||||
}
|
} else {
|
||||||
blossomServers = make([]string, len(servers.Items))
|
blossomServers = make([]string, len(servers.Items))
|
||||||
for i, s := range servers.Items {
|
for i, s := range servers.Items {
|
||||||
blossomServers[i] = s.Value()
|
blossomServers[i] = s.Value()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
blossomServers = nostr.AppendUnique(blossomServers, c.StringSlice("server")...)
|
||||||
signer := keyer.NewReadOnlySigner(pk)
|
if len(blossomServers) == 0 {
|
||||||
|
return fmt.Errorf("no blossom servers advertised in manifest or kind:10063")
|
||||||
|
}
|
||||||
|
|
||||||
for path, hash := range mnf.Paths {
|
for path, hash := range mnf.Paths {
|
||||||
relPath := strings.TrimPrefix(path, "/")
|
relPath := strings.TrimPrefix(path, "/")
|
||||||
@@ -319,12 +351,13 @@ var nsite = &cli.Command{
|
|||||||
|
|
||||||
var downloadErr error
|
var downloadErr error
|
||||||
for _, server := range blossomServers {
|
for _, server := range blossomServers {
|
||||||
client := blossom.NewClient(server, signer)
|
client := blossom.NewClient(server, readOnlySigner)
|
||||||
data, err := client.Download(ctx, hash)
|
data, err := client.Download(ctx, hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
downloadErr = err
|
downloadErr = errors.Join(downloadErr, fmt.Errorf("%s: %w", server, err))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.WriteFile(fullPath, data, 0o644); err != nil {
|
if err := os.WriteFile(fullPath, data, 0o644); err != nil {
|
||||||
return fmt.Errorf("failed to write %s: %w", fullPath, err)
|
return fmt.Errorf("failed to write %s: %w", fullPath, err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user