mirror of
https://github.com/nbd-wtf/go-nostr.git
synced 2025-06-19 21:32:39 +02:00
support wasm (#163)
This commit is contained in:
parent
a7a66add61
commit
63919cf685
@ -145,6 +145,14 @@ But to use it you need the host to have it installed as a shared library and CGO
|
|||||||
|
|
||||||
To use it, use `-tags=libsecp256k1` whenever you're compiling your program that uses this library.
|
To use it, use `-tags=libsecp256k1` whenever you're compiling your program that uses this library.
|
||||||
|
|
||||||
|
### Test for Wasm
|
||||||
|
|
||||||
|
Install [wasmbrowsertest](https://github.com/agnivade/wasmbrowsertest), then run tests:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
TEST_RELAY_URL=<relay_url> GOOS=js GOARCH=wasm go test -short ./...
|
||||||
|
```
|
||||||
|
|
||||||
## Warning: risk of goroutine bloat (if used incorrectly)
|
## Warning: risk of goroutine bloat (if used incorrectly)
|
||||||
|
|
||||||
Remember to cancel subscriptions, either by calling `.Unsub()` on them or ensuring their `context.Context` will be canceled at some point.
|
Remember to cancel subscriptions, either by calling `.Unsub()` on them or ensuring their `context.Context` will be canceled at some point.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build !js
|
||||||
|
|
||||||
package nostr
|
package nostr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -179,3 +181,7 @@ func (c *Connection) ReadMessage(ctx context.Context, buf io.Writer) error {
|
|||||||
func (c *Connection) Close() error {
|
func (c *Connection) Close() error {
|
||||||
return c.conn.Close()
|
return c.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Connection) Ping(ctx context.Context) error {
|
||||||
|
return wsutil.WriteClientMessage(c.conn, ws.OpPing, nil)
|
||||||
|
}
|
||||||
|
55
connection_js.go
Normal file
55
connection_js.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//go:build js
|
||||||
|
|
||||||
|
package nostr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
ws "github.com/coder/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Connection struct {
|
||||||
|
conn *ws.Conn
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewConnection(ctx context.Context, url string, requestHeader http.Header, tlsConfig *tls.Config) (*Connection, error) {
|
||||||
|
c, _, err := ws.Dial(ctx, url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Connection{
|
||||||
|
conn: c,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection) WriteMessage(ctx context.Context, data []byte) error {
|
||||||
|
if err := c.conn.Write(ctx, ws.MessageBinary, data); err != nil {
|
||||||
|
return fmt.Errorf("failed to write message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection) ReadMessage(ctx context.Context, buf io.Writer) error {
|
||||||
|
_, reader, err := c.conn.Reader(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get reader: %w", err)
|
||||||
|
}
|
||||||
|
if _, err := io.Copy(buf, reader); err != nil {
|
||||||
|
return fmt.Errorf("failed to read message: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection) Close() error {
|
||||||
|
return c.conn.Close(ws.StatusNormalClosure, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Connection) Ping(ctx context.Context) error {
|
||||||
|
return c.conn.Ping(ctx)
|
||||||
|
}
|
1
go.mod
1
go.mod
@ -6,6 +6,7 @@ require (
|
|||||||
github.com/bluekeyes/go-gitdiff v0.7.1
|
github.com/bluekeyes/go-gitdiff v0.7.1
|
||||||
github.com/btcsuite/btcd/btcec/v2 v2.3.4
|
github.com/btcsuite/btcd/btcec/v2 v2.3.4
|
||||||
github.com/btcsuite/btcd/btcutil v1.1.3
|
github.com/btcsuite/btcd/btcutil v1.1.3
|
||||||
|
github.com/coder/websocket v1.8.12
|
||||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0
|
||||||
github.com/dgraph-io/ristretto v1.0.0
|
github.com/dgraph-io/ristretto v1.0.0
|
||||||
github.com/fiatjaf/eventstore v0.9.0
|
github.com/fiatjaf/eventstore v0.9.0
|
||||||
|
2
go.sum
2
go.sum
@ -37,6 +37,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
|
|||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw=
|
||||||
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA=
|
||||||
|
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
|
||||||
|
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
@ -59,11 +59,11 @@ func TestDoWorkShort(t *testing.T) {
|
|||||||
Content: "It's just me mining my own business",
|
Content: "It's just me mining my own business",
|
||||||
PubKey: "a48380f4cfcc1ad5378294fcac36439770f9c878dd880ffa94bb74ea54a6f243",
|
PubKey: "a48380f4cfcc1ad5378294fcac36439770f9c878dd880ffa94bb74ea54a6f243",
|
||||||
}
|
}
|
||||||
pow, err := DoWork(context.Background(), event, 0)
|
pow, err := DoWork(context.Background(), event, 2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
testNonceTag(t, pow, 0)
|
testNonceTag(t, pow, 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDoWorkLong(t *testing.T) {
|
func TestDoWorkLong(t *testing.T) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build !js
|
||||||
|
|
||||||
package nip96
|
package nip96
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
4
relay.go
4
relay.go
@ -12,8 +12,6 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gobwas/ws"
|
|
||||||
"github.com/gobwas/ws/wsutil"
|
|
||||||
"github.com/puzpuzpuz/xsync/v3"
|
"github.com/puzpuzpuz/xsync/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -183,7 +181,7 @@ func (r *Relay) ConnectWithTLS(ctx context.Context, tlsConfig *tls.Config) error
|
|||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if r.Connection != nil {
|
if r.Connection != nil {
|
||||||
err := wsutil.WriteClientMessage(r.Connection.conn, ws.OpPing, nil)
|
err := r.Connection.Ping(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
InfoLogger.Printf("{%s} error writing ping: %v; closing websocket", r.URL, err)
|
InfoLogger.Printf("{%s} error writing ping: %v; closing websocket", r.URL, err)
|
||||||
r.Close() // this should trigger a context cancelation
|
r.Close() // this should trigger a context cancelation
|
||||||
|
84
relay_js_test.go
Normal file
84
relay_js_test.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
//go:build js
|
||||||
|
|
||||||
|
package nostr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestConnectContext(t *testing.T) {
|
||||||
|
url := os.Getenv("TEST_RELAY_URL")
|
||||||
|
if url == "" {
|
||||||
|
t.Fatal("please set the environment: $TEST_RELAY_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
// relay client
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
r, err := RelayConnect(ctx, url)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
defer r.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConnectContextCanceled(t *testing.T) {
|
||||||
|
url := os.Getenv("TEST_RELAY_URL")
|
||||||
|
if url == "" {
|
||||||
|
t.Fatal("please set the environment: $TEST_RELAY_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
// relay client
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
cancel() // make ctx expired
|
||||||
|
_, err := RelayConnect(ctx, url)
|
||||||
|
assert.ErrorIs(t, err, context.Canceled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPublish(t *testing.T) {
|
||||||
|
url := os.Getenv("TEST_RELAY_URL")
|
||||||
|
if url == "" {
|
||||||
|
t.Fatal("please set the environment: $TEST_RELAY_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
// test note to be sent over websocket
|
||||||
|
priv, pub := makeKeyPair(t)
|
||||||
|
textNote := Event{
|
||||||
|
Kind: KindTextNote,
|
||||||
|
Content: "hello",
|
||||||
|
CreatedAt: Timestamp(1672068534), // random fixed timestamp
|
||||||
|
Tags: Tags{[]string{"foo", "bar"}},
|
||||||
|
PubKey: pub,
|
||||||
|
}
|
||||||
|
err := textNote.Sign(priv)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
// connect a client and send the text note
|
||||||
|
rl := mustRelayConnect(t, url)
|
||||||
|
err = rl.Publish(context.Background(), textNote)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeKeyPair(t *testing.T) (priv, pub string) {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
privkey := GeneratePrivateKey()
|
||||||
|
pubkey, err := GetPublicKey(privkey)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
return privkey, pubkey
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustRelayConnect(t *testing.T, url string) *Relay {
|
||||||
|
t.Helper()
|
||||||
|
|
||||||
|
rl, err := RelayConnect(context.Background(), url)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return rl
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build !js
|
||||||
|
|
||||||
package nostr
|
package nostr
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//go:build !sqlite_math_functions
|
//go:build !js && !sqlite_math_functions
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
//go:build !js
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
//go:build !sqlite_math_functions
|
//go:build !js && !sqlite_math_functions
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user