mirror of
https://github.com/fiatjaf/nak.git
synced 2025-12-08 16:48:51 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e4a546212 | ||
|
|
55c9d4ee45 | ||
|
|
550c89d8d7 | ||
|
|
1e9be3ed84 | ||
|
|
79cbc57dde | ||
|
|
1e237b4c42 | ||
|
|
89ec8b9822 | ||
|
|
fba83ea39e | ||
|
|
bd5569955c | ||
|
|
35ea2582d8 | ||
|
|
fa63dbfea3 | ||
|
|
a6509909d0 | ||
|
|
239dd2d42a | ||
|
|
0073c9bdf1 | ||
|
|
b5bd2aecf6 | ||
|
|
f27ac6c0e3 |
97
.github/workflows/smoke-test-release.yml
vendored
Normal file
97
.github/workflows/smoke-test-release.yml
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
name: Smoke test the binary
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["build cli for all platforms"]
|
||||
types:
|
||||
- completed
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
smoke-test-linux-amd64:
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
||||
steps:
|
||||
- name: Download and smoke test latest binary
|
||||
run: |
|
||||
set -eo pipefail # Exit on error, and on pipe failures
|
||||
|
||||
echo "Downloading nak binary from releases"
|
||||
RELEASE_URL="https://api.github.com/repos/fiatjaf/nak/releases/latest"
|
||||
wget $(wget -q -O - ${RELEASE_URL} | jq -r '.assets[] | select(.name | contains("linux-amd64")) | .browser_download_url') -O nak -nv
|
||||
chmod +x nak
|
||||
|
||||
echo "Running basic tests..."
|
||||
./nak --version
|
||||
|
||||
# Generate and manipulate keys
|
||||
echo "Testing key operations..."
|
||||
SECRET_KEY=$(./nak key generate)
|
||||
PUBLIC_KEY=$(echo $SECRET_KEY | ./nak key public)
|
||||
echo "Generated key pair: $PUBLIC_KEY"
|
||||
|
||||
# Create events
|
||||
echo "Testing event creation..."
|
||||
./nak event -c "hello world"
|
||||
./nak event --ts "2 days ago" -c "event with timestamp"
|
||||
./nak event -k 1 -t "t=test" -c "event with tag"
|
||||
|
||||
# Test NIP-19 encoding/decoding
|
||||
echo "Testing NIP-19 encoding/decoding..."
|
||||
NSEC=$(echo $SECRET_KEY | ./nak encode nsec)
|
||||
echo "Encoded nsec: $NSEC"
|
||||
./nak encode npub 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
NOTE_ID="5ae731bbc7711f78513da14927c48cc7143a91e6cad0565fdc4d73b8967a7d59"
|
||||
NOTE1=$(./nak encode note $NOTE_ID)
|
||||
echo "Encoded note1: $NOTE1"
|
||||
./nak decode $NOTE1
|
||||
./nak decode npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6
|
||||
|
||||
# Test event verification
|
||||
echo "Testing event verification..."
|
||||
# Create an event and verify it
|
||||
VERIFY_EVENT=$(./nak event -c "verify me")
|
||||
echo $VERIFY_EVENT | ./nak verify
|
||||
|
||||
# Test PoW
|
||||
echo "Testing PoW..."
|
||||
./nak event -c "testing pow" --pow 8
|
||||
|
||||
# Test NIP-49 key encryption/decryption
|
||||
echo "Testing NIP-49 key encryption/decryption..."
|
||||
ENCRYPTED_KEY=$(./nak key encrypt $SECRET_KEY "testpassword")
|
||||
echo "Encrypted key: ${ENCRYPTED_KEY:0:20}..."
|
||||
DECRYPTED_KEY=$(./nak key decrypt $ENCRYPTED_KEY "testpassword")
|
||||
if [ "$DECRYPTED_KEY" != "$SECRET_KEY" ]; then
|
||||
echo "NIP-49 encryption/decryption test failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test multi-value tags
|
||||
echo "Testing multi-value tags..."
|
||||
./nak event --ts "yesterday" -t "e=f59911b561c37c90b01e9e5c2557307380835c83399756f4d62d8167227e420a;wss://relay.example.com;root" -c "Testing multi-value tags"
|
||||
|
||||
# Test relay operations (with a public relay)
|
||||
echo "Testing relay operations..."
|
||||
# Publish a simple event to a public relay
|
||||
EVENT_JSON=$(./nak event --sec $SECRET_KEY -c "Test from nak smoke test" nos.lol)
|
||||
EVENT_ID=$(echo $EVENT_JSON | jq -r .id)
|
||||
echo "Published event ID: $EVENT_ID"
|
||||
|
||||
# Wait a moment for propagation
|
||||
sleep 2
|
||||
|
||||
# Fetch the event we just published
|
||||
./nak req -i $EVENT_ID nos.lol
|
||||
|
||||
# Test serving (just start and immediately kill)
|
||||
echo "Testing serve command..."
|
||||
timeout 2s ./nak serve || true
|
||||
|
||||
# Test filesystem mount (just start and immediately kill)
|
||||
echo "Testing fs mount command..."
|
||||
mkdir -p /tmp/nostr-mount
|
||||
timeout 2s ./nak fs --sec $SECRET_KEY /tmp/nostr-mount || true
|
||||
|
||||
echo "All tests passed"
|
||||
14
README.md
14
README.md
@@ -128,11 +128,18 @@ type the password to decrypt your secret key: **********
|
||||
985d66d2644dfa7676e26046914470d66ebc7fa783a3f57f139fde32d0d631d7
|
||||
```
|
||||
|
||||
### sign an event using a remote NIP-46 bunker
|
||||
### sign an event using [Amber](https://github.com/greenart7c3/Amber) (or other bunker provider)
|
||||
```shell
|
||||
~> export NOSTR_CLIENT_KEY="$(nak key generate)"
|
||||
~> nak event --sec 'bunker://a9e0f110f636f3191644110c19a33448daf09d7cda9708a769e91b7e91340208?relay=wss%3A%2F%2Frelay.damus.io&relay=wss%3A%2F%2Frelay.nsecbunker.com&relay=wss%3A%2F%2Fnos.lol&secret=TWfGbjQCLxUf' -c 'hello from bunker'
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Remember to set a `NOSTR_CLIENT_KEY` permanently on your shell, otherwise you'll only be able to use the bunker once. For `bash`:
|
||||
> ```shell
|
||||
> echo 'export NOSTR_CLIENT_KEY="$(nak key generate)"' >> ~/.bashrc
|
||||
> ```
|
||||
|
||||
### sign an event using a NIP-49 encrypted key
|
||||
```shell
|
||||
~> nak event --sec ncryptsec1qggx54cg270zy9y8krwmfz29jyypsuxken2fkk99gr52qhje968n6mwkrfstqaqhq9eq94pnzl4nff437l4lp4ur2cs4f9um8738s35l2esx2tas48thtfhrk5kq94pf9j2tpk54yuermra0xu6hl5ls -c 'hello from encrypted key'
|
||||
@@ -271,6 +278,11 @@ echo "#surely you're joking, mr npub1l2vyh47mk2p0qlsku7hg0vn29faehy9hy34ygaclpn6
|
||||
# and there is a --confirm flag that gives you a chance to confirm before actually publishing the result to relays.
|
||||
```
|
||||
|
||||
### record and publish an audio note of 10s (yakbak etc) signed from a bunker
|
||||
```shell
|
||||
ffmpeg -f alsa -i default -f webm -t 00:00:03 pipe:1 | nak blossom --server blossom.primal.net upload | jq -rc '{content: .url}' | nak event -k 1222 --sec 'bunker://urlgoeshere' pyramid.fiatjaf.com nostr.wine
|
||||
```
|
||||
|
||||
## contributing to this repository
|
||||
|
||||
Use NIP-34 to send your patches to `naddr1qqpkucttqy28wumn8ghj7un9d3shjtnwdaehgu3wvfnsz9nhwden5te0wfjkccte9ehx7um5wghxyctwvsq3gamnwvaz7tmjv4kxz7fwv3sk6atn9e5k7q3q80cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsxpqqqpmej2wctpn`.
|
||||
|
||||
@@ -17,10 +17,9 @@ import (
|
||||
|
||||
func call(t *testing.T, cmd string) string {
|
||||
var output strings.Builder
|
||||
stdout = func(a ...any) (int, error) {
|
||||
stdout = func(a ...any) {
|
||||
output.WriteString(fmt.Sprint(a...))
|
||||
output.WriteString("\n")
|
||||
return 0, nil
|
||||
}
|
||||
err := app.Run(t.Context(), strings.Split(cmd, " "))
|
||||
require.NoError(t, err)
|
||||
|
||||
8
event.go
8
event.go
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"slices"
|
||||
@@ -9,6 +10,7 @@ import (
|
||||
"time"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/keyer"
|
||||
"fiatjaf.com/nostr/nip13"
|
||||
"fiatjaf.com/nostr/nip19"
|
||||
"github.com/fatih/color"
|
||||
@@ -168,6 +170,7 @@ example:
|
||||
evt.Content = ""
|
||||
|
||||
kindWasSupplied := strings.Contains(stdinEvent, `"kind"`)
|
||||
contentWasSupplied := strings.Contains(stdinEvent, `"content"`)
|
||||
mustRehashAndResign := false
|
||||
|
||||
if err := easyjson.Unmarshal([]byte(stdinEvent), &evt); err != nil {
|
||||
@@ -194,7 +197,7 @@ example:
|
||||
evt.Content = content
|
||||
}
|
||||
mustRehashAndResign = true
|
||||
} else if evt.Content == "" && evt.Kind == 1 {
|
||||
} else if !contentWasSupplied && evt.Content == "" && evt.Kind == 1 {
|
||||
evt.Content = "hello from the nostr army knife"
|
||||
mustRehashAndResign = true
|
||||
}
|
||||
@@ -287,6 +290,9 @@ example:
|
||||
return nil
|
||||
}
|
||||
} else if err := kr.SignEvent(ctx, &evt); err != nil {
|
||||
if _, isBunker := kr.(keyer.BunkerSigner); isBunker && errors.Is(ctx.Err(), context.DeadlineExceeded) {
|
||||
err = fmt.Errorf("timeout waiting for bunker to respond")
|
||||
}
|
||||
return fmt.Errorf("error signing with provided key: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
96
filter.go
Normal file
96
filter.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"github.com/mailru/easyjson"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var filter = &cli.Command{
|
||||
Name: "filter",
|
||||
Usage: "applies an event filter to an event to see if it matches.",
|
||||
Description: `
|
||||
example:
|
||||
echo '{"kind": 1, "content": "hello"}' | nak filter -k 1
|
||||
nak filter '{"kind": 1, "content": "hello"}' -k 1
|
||||
nak filter '{"kind": 1, "content": "hello"}' '{"kinds": [1]}' -k 0
|
||||
`,
|
||||
DisableSliceFlagSeparator: true,
|
||||
Flags: reqFilterFlags,
|
||||
ArgsUsage: "[event_json] [base_filter_json]",
|
||||
Action: func(ctx context.Context, c *cli.Command) error {
|
||||
args := c.Args().Slice()
|
||||
|
||||
var baseFilter nostr.Filter
|
||||
var baseEvent nostr.Event
|
||||
|
||||
if len(args) == 2 {
|
||||
// two arguments: first is event, second is base filter
|
||||
if err := easyjson.Unmarshal([]byte(args[0]), &baseEvent); err != nil {
|
||||
return fmt.Errorf("invalid base event: %w", err)
|
||||
}
|
||||
if err := easyjson.Unmarshal([]byte(args[1]), &baseFilter); err != nil {
|
||||
return fmt.Errorf("invalid base filter: %w", err)
|
||||
}
|
||||
} else if len(args) == 1 {
|
||||
if isPiped() {
|
||||
// one argument + stdin: argument is base filter
|
||||
if err := easyjson.Unmarshal([]byte(args[0]), &baseFilter); err != nil {
|
||||
return fmt.Errorf("invalid base filter: %w", err)
|
||||
}
|
||||
} else {
|
||||
// one argument, no stdin: argument is event
|
||||
if err := easyjson.Unmarshal([]byte(args[0]), &baseEvent); err != nil {
|
||||
return fmt.Errorf("invalid base event: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// apply flags to filter
|
||||
if err := applyFlagsToFilter(c, &baseFilter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if there is no stdin we'll still get an empty object here
|
||||
for evtj := range getJsonsOrBlank() {
|
||||
var evt nostr.Event
|
||||
if err := easyjson.Unmarshal([]byte(evtj), &evt); err != nil {
|
||||
ctx = lineProcessingError(ctx, "invalid event: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
// merge that with the base event
|
||||
if evt.ID == nostr.ZeroID {
|
||||
evt.ID = baseEvent.ID
|
||||
}
|
||||
if evt.PubKey == nostr.ZeroPK {
|
||||
evt.PubKey = baseEvent.PubKey
|
||||
}
|
||||
if evt.Sig == [64]byte{} {
|
||||
evt.Sig = baseEvent.Sig
|
||||
}
|
||||
if evt.Content == "" {
|
||||
evt.Content = baseEvent.Content
|
||||
}
|
||||
if len(evt.Tags) == 0 {
|
||||
evt.Tags = baseEvent.Tags
|
||||
}
|
||||
if evt.CreatedAt == 0 {
|
||||
evt.CreatedAt = baseEvent.CreatedAt
|
||||
}
|
||||
|
||||
if baseFilter.Matches(evt) {
|
||||
stdout(evt)
|
||||
} else {
|
||||
fmt.Println(baseFilter.LimitZero)
|
||||
logverbose("event %s didn't match %s", evt, baseFilter)
|
||||
}
|
||||
}
|
||||
|
||||
exitIfLineProcessingError(ctx)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
14
go.mod
14
go.mod
@@ -4,9 +4,9 @@ go 1.24.1
|
||||
|
||||
require (
|
||||
fiatjaf.com/lib v0.3.1
|
||||
fiatjaf.com/nostr v0.0.0-20250522115245-f38ce069a93d
|
||||
fiatjaf.com/nostr v0.0.0-20250627165101-028a1637fbd0
|
||||
github.com/bep/debounce v1.2.1
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.5
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0
|
||||
github.com/fatih/color v1.16.0
|
||||
@@ -19,7 +19,7 @@ require (
|
||||
github.com/mattn/go-tty v0.0.7
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/urfave/cli/v3 v3.0.0-beta1
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b
|
||||
golang.org/x/term v0.30.0
|
||||
)
|
||||
|
||||
@@ -30,7 +30,7 @@ require (
|
||||
github.com/btcsuite/btcd v0.24.2 // indirect
|
||||
github.com/btcsuite/btcd/btcutil v1.1.5 // indirect
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
|
||||
github.com/bytedance/sonic v1.13.2 // indirect
|
||||
github.com/bytedance/sonic v1.13.3 // indirect
|
||||
github.com/bytedance/sonic/loader v0.2.4 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chzyer/logex v1.1.10 // indirect
|
||||
@@ -55,7 +55,7 @@ require (
|
||||
github.com/jalaali/go-jalaali v0.0.0-20210801064154-80525e88d958 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/magefile/mage v1.14.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
@@ -77,10 +77,10 @@ require (
|
||||
github.com/wasilibs/go-re2 v1.3.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/arch v0.17.0 // indirect
|
||||
golang.org/x/arch v0.18.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.37.0 // indirect
|
||||
golang.org/x/sync v0.14.0 // indirect
|
||||
golang.org/x/sync v0.15.0 // indirect
|
||||
golang.org/x/sys v0.33.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
google.golang.org/protobuf v1.36.2 // indirect
|
||||
|
||||
30
go.sum
30
go.sum
@@ -1,10 +1,10 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
fiatjaf.com/lib v0.3.1 h1:/oFQwNtFRfV+ukmOCxfBEAuayoLwXp4wu2/fz5iHpwA=
|
||||
fiatjaf.com/lib v0.3.1/go.mod h1:Ycqq3+mJ9jAWu7XjbQI1cVr+OFgnHn79dQR5oTII47g=
|
||||
fiatjaf.com/nostr v0.0.0-20250521022139-d3fb25441ab3 h1:JRtme8g4UQ5KYlxI31wBa8YMWmAxvxdwtNn+PiI/XCs=
|
||||
fiatjaf.com/nostr v0.0.0-20250521022139-d3fb25441ab3/go.mod h1:VPs38Fc8J1XAErV750CXAmMUqIq3XEX9VZVj/LuQzzM=
|
||||
fiatjaf.com/nostr v0.0.0-20250522115245-f38ce069a93d h1:sl/BOXW5eK7v+cchMMEZvnzQW+n/jWiHGQn+CRt5m5Q=
|
||||
fiatjaf.com/nostr v0.0.0-20250522115245-f38ce069a93d/go.mod h1:VPs38Fc8J1XAErV750CXAmMUqIq3XEX9VZVj/LuQzzM=
|
||||
fiatjaf.com/nostr v0.0.0-20250610194330-027d016d9706 h1:G0xS5h9dsbODWh+f8rYvDkY328h79MsNs2dGPGqm8nY=
|
||||
fiatjaf.com/nostr v0.0.0-20250610194330-027d016d9706/go.mod h1:VPs38Fc8J1XAErV750CXAmMUqIq3XEX9VZVj/LuQzzM=
|
||||
fiatjaf.com/nostr v0.0.0-20250627165101-028a1637fbd0 h1:Se07jECWueD3fZyaHO08oIzFOPwT6A6wNPQ8QWccX5c=
|
||||
fiatjaf.com/nostr v0.0.0-20250627165101-028a1637fbd0/go.mod h1:VPs38Fc8J1XAErV750CXAmMUqIq3XEX9VZVj/LuQzzM=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/FastFilter/xorfilter v0.2.1 h1:lbdeLG9BdpquK64ZsleBS8B4xO/QW1IM0gMzF7KaBKc=
|
||||
github.com/FastFilter/xorfilter v0.2.1/go.mod h1:aumvdkhscz6YBZF9ZA/6O4fIoNod4YR50kIVGGZ7l9I=
|
||||
@@ -24,8 +24,8 @@ github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY=
|
||||
github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.5 h1:dpAlnAwmT1yIBm3exhT1/8iUSD98RDJM5vqJVQDQLiU=
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.5/go.mod h1:m22FrOAiuxl/tht9wIqAoGHcbnCCaPWyauO8y2LGGtQ=
|
||||
github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A=
|
||||
github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE=
|
||||
github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8=
|
||||
@@ -43,8 +43,8 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku
|
||||
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic v1.13.3 h1:MS8gmaH16Gtirygw7jV91pDCN33NyMrPbN7qiYhEsF0=
|
||||
github.com/bytedance/sonic v1.13.3/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||
github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY=
|
||||
github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI=
|
||||
@@ -157,6 +157,8 @@ github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYW
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
@@ -243,16 +245,16 @@ github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZ
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
golang.org/x/arch v0.17.0 h1:4O3dfLzd+lQewptAHqjewQZQDyEdejz3VwgeYwkZneU=
|
||||
golang.org/x/arch v0.17.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/arch v0.18.0 h1:WN9poc33zL4AzGxqf8VtpKUnGvMi8O9lhNyBMF/85qc=
|
||||
golang.org/x/arch v0.18.0/go.mod h1:bdwinDaKcfZUGpH09BB7ZmOfhalA8lQdzl62l8gGWsk=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
@@ -272,8 +274,8 @@ golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAG
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
||||
@@ -424,7 +424,7 @@ func askConfirmation(msg string) bool {
|
||||
}
|
||||
defer tty.Close()
|
||||
|
||||
fmt.Fprintf(os.Stderr, color.YellowString(msg))
|
||||
log(color.YellowString(msg))
|
||||
answer, err := tty.ReadString()
|
||||
if err != nil {
|
||||
return false
|
||||
|
||||
@@ -75,9 +75,14 @@ func gatherSecretKeyOrBunkerFromArguments(ctx context.Context, c *cli.Command) (
|
||||
clientKey = nostr.Generate()
|
||||
}
|
||||
|
||||
logverbose("[nip46]: connecting to %s with client key %s", bunkerURL, clientKey.Hex())
|
||||
|
||||
bunker, err := nip46.ConnectBunker(ctx, clientKey, bunkerURL, nil, func(s string) {
|
||||
log(color.CyanString("[nip46]: open the following URL: %s"), s)
|
||||
})
|
||||
if err != nil {
|
||||
return nostr.SecretKey{}, nil, fmt.Errorf("failed to connect to %s: %w", bunkerURL, err)
|
||||
}
|
||||
|
||||
return nostr.SecretKey{}, bunker, err
|
||||
}
|
||||
@@ -139,7 +144,7 @@ func askPassword(msg string, shouldAskAgain func(answer string) bool) (string, e
|
||||
defer tty.Close()
|
||||
for {
|
||||
// print the prompt to stderr so it's visible to the user
|
||||
fmt.Fprintf(os.Stderr, color.YellowString(msg))
|
||||
log(color.YellowString(msg))
|
||||
|
||||
// read password from TTY with masking
|
||||
password, err := tty.ReadPassword()
|
||||
|
||||
3
main.go
3
main.go
@@ -27,6 +27,7 @@ var app = &cli.Command{
|
||||
Commands: []*cli.Command{
|
||||
event,
|
||||
req,
|
||||
filter,
|
||||
fetch,
|
||||
count,
|
||||
decode,
|
||||
@@ -124,7 +125,7 @@ func main() {
|
||||
|
||||
if err := app.Run(context.Background(), os.Args); err != nil {
|
||||
if err != nil {
|
||||
log(color.YellowString(err.Error()) + "\n")
|
||||
log("%s\n", color.YellowString(err.Error()))
|
||||
}
|
||||
colors.reset()
|
||||
os.Exit(1)
|
||||
|
||||
2
mcp.go
2
mcp.go
@@ -169,7 +169,7 @@ var mcpServer = &cli.Command{
|
||||
l++
|
||||
pm, _ := sdk.ParseMetadata(result.Event)
|
||||
res.WriteString(fmt.Sprintf("\n\nResult %d\nUser name: \"%s\"\nPublic key: \"%s\"\nDescription: \"%s\"\n",
|
||||
l, pm.ShortName, pm.PubKey.Hex(), pm.About))
|
||||
l, pm.ShortName(), pm.PubKey.Hex(), pm.About))
|
||||
|
||||
if l >= int(limit) {
|
||||
break
|
||||
|
||||
@@ -175,7 +175,7 @@ func (r *NostrRoot) CreateEventDir(
|
||||
|
||||
if event.Kind == 1 {
|
||||
if pointer := nip10.GetThreadRoot(event.Tags); pointer != nil {
|
||||
nevent := nip19.EncodePointer(*pointer)
|
||||
nevent := nip19.EncodePointer(pointer)
|
||||
h.AddChild("@root", h.NewPersistentInode(
|
||||
r.ctx,
|
||||
&fs.MemSymlink{
|
||||
@@ -185,7 +185,7 @@ func (r *NostrRoot) CreateEventDir(
|
||||
), true)
|
||||
}
|
||||
if pointer := nip10.GetImmediateParent(event.Tags); pointer != nil {
|
||||
nevent := nip19.EncodePointer(*pointer)
|
||||
nevent := nip19.EncodePointer(pointer)
|
||||
h.AddChild("@parent", h.NewPersistentInode(
|
||||
r.ctx,
|
||||
&fs.MemSymlink{
|
||||
|
||||
Reference in New Issue
Block a user