nbd-wtf / nostr-tools

Tools for developing Nostr clients.
The Unlicense
691 stars 193 forks source link

Nostr connection times out in Docker environment #431

Open gaboe opened 1 week ago

gaboe commented 1 week ago

Description

When running our application in a Docker container, we're experiencing connection timeouts when trying to connect to Nostr relays. The same code works fine on macOS bun, but fails in bun the Docker environment.

Also i have tried using nodejs with polyfill hack, but it didn't work either https://github.com/nbd-wtf/nostr-tools/pull/347

Is this package supossed to work on server?

import { defineEventHandler } from "h3";
import { SimplePool } from "nostr-tools";
import { nip19, nip04 } from "nostr-tools";
import { finalizeEvent, getPublicKey } from "nostr-tools/pure";

const RELAYS = [
  "wss://relay.damus.io",
  "wss://relay.primal.net",
  "wss://relay.0xchat.com",
  "wss://relay.siamstr.com",
];

const secretKey = nip19.decode("nsec1").data;

export default defineEventHandler(async () => {
  const pool = new SimplePool();
  const recipientPubkeys = ["npub"].map(
    (pubkey) => nip19.decode(pubkey).data as string
  );

  const content = "test";

  try {
    const relayConnections = await Promise.all(
      RELAYS.map((relay) => pool.ensureRelay(relay))
    );

    for (const recipientPubkey of recipientPubkeys) {
      const encryptedContent = await nip04.encrypt(
        secretKey,
        recipientPubkey,
        content
      );

      const eventTemplate = {
        kind: 4,
        created_at: Math.floor(Date.now() / 1000),
        tags: [["p", recipientPubkey]],
        content: encryptedContent,
        pubkey: getPublicKey(secretKey),
      };

      const signedEvent = finalizeEvent(eventTemplate, secretKey);

      const pubs = relayConnections.map((relay) => relay.publish(signedEvent));
      const failedRelays = [];
      await Promise.all(
        pubs.map(async (pub, i) => {
          try {
            await pub;
          } catch (err) {
            failedRelays.push(RELAYS[i]);
          }
        })
      );
      console.log("Published private message to Nostr!");

      if (failedRelays.length > 0) {
        throw new Error("Failed relays: " + failedRelays.join(", "));
      }

      return {
        success: true,
        message: "Form submitted and private notification sent",
      };
    }
  } catch (error) {
    console.error(
      "Error sending private message to Nostr:",
      error,
      JSON.stringify(error),
      error instanceof Error ? "Failed relays: " + error.message : ""
    );
    return {
      success: false,
      message: "Form submitted but private notification failed",
    };
  } finally {
    await pool.close(RELAYS);
  }
});
gaboe commented 1 week ago

I have added whole minimal reproducible repo https://github.com/gaboe/nostr-api

I have been strugling wih this for few hours, i would appreciate any help.

antonioconselheiro commented 1 week ago

Did you tried to use useWebSocketImplementation from https://github.com/nbd-wtf/nostr-tools?tab=readme-ov-file#interacting-with-multiple-relays?

I mean, like this config:

import { useWebSocketImplementation } from 'nostr-tools/pool'

useWebSocketImplementation(require('ws'))

I think you can try this too:

Object.assign(global, { WebSocket: require('ws') });