0%

Nostr: nostr-tools のトラブルシューティング

JavaScript モジュールで nostr-tools を使用する場合のトラブルシューティング。

環境

  • Node.js 16.16.0
  • nostr-tools 1.3.2

SyntaxError: Named export 'SimplePool' not found. The requested module 'nostr-tools' is a CommonJS module, which may not support all module.exports as named exports.

注: 1.6.0 で修正された。

1
import { SimplePool } from "nostr-tools";

以下のエラーが発生する。

1
2
3
4
5
6
7
import { SimplePool } from "nostr-tools";
^^^^^^^^^^
SyntaxError: Named export 'SimplePool' not found. The requested module 'nostr-tools' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'nostr-tools';
const { SimplePool } = pkg;

import をメッセージのとおり書き換える。

1
2
import pkg from "nostr-tools";
const { SimplePool } = pkg;

ReferenceError: WebSocket is not defined

1
2
3
4
      ws = new WebSocket(url);
^

ReferenceError: WebSocket is not defined

websocket-polyfill をインストールしてインポートする。

1
npm i websocket-polyfill
1
import "websocket-polyfill";

https://github.com/nbd-wtf/nostr-tools#interacting-with-a-relay

TypeError: Cannot read properties of undefined (reading 'sendCloseFrame')

1
2
3
4
5
6
7
8
9
const pool = new SimplePool();
const posts = await pool.list(RELAYS, [
{
authors: [PK],
kinds: [1],
},
]);
...
await pool.close(RELAYS);

pool.close で以下のエラーが発生する。

1
2
3
4
            this.connection_.sendCloseFrame();
^

TypeError: Cannot read properties of undefined (reading 'sendCloseFrame')

未解決。暫定的に、pool.close をコメントアウトして、process.exit で強制終了させる。

1
2
3
...
// await pool.close(RELAYS);
process.exit();

pool.list のタイムアウト

1
2
3
4
5
6
7
const pool = new SimplePool();
const posts = await pool.list(RELAYS, [
{
authors: [PK],
kinds: [1],
},
]);

pool.list でタイムアウトが発生する場合がある。

pool.list の前に以下のコードを追加し、nostr-tools のタイムアウトを長くする。

1
2
const temp = setTimeout;
setTimeout = (func) => temp(func, 30 * 1000);

注: 1.6.3 でタイムアウトを設定できるようになった。

1
const pool = new SimplePool({ eoseSubTimeout: 30 * 1000, getTimeout: 30 * 1000 });

UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block

注: 1.6.1 で修正された。

参考: Websocket connection failure via pool results in uncaught exception · Issue #130 · nbd-wtf/nostr-tools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const RELAYS = [
"wss://nos.lol",
"wss://nostr-pub.wellorder.net",
"wss://nostr.bitcoiner.social",
"wss://nostr.mom",
"wss://nostr.oxtr.dev",
"wss://relay.damus.io",
"wss://relay.nostr.bg",
];

const pool = new SimplePool();
const posts = await pool.list(RELAYS, [
{
authors: [PK],
kinds: [1],
},
]);

pool.list で以下のエラーが発生する。

1
2
3
4
5
6
7
node:internal/process/promises:279
triggerUncaughtException(err, true /* fromPromise */);
^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "undefined".] {
code: 'ERR_UNHANDLED_REJECTION'
}

未解決。暫定的に、エラーを引き起こすリレー サーバーを削除する。

pool.publishwss://xxxx not connected

1
2
const pool = new SimplePool();
pool.publish(RELAYS, event);

pool.publish の前に pool.ensureRelay を呼び出す必要がある。

1
2
3
const pool = new SimplePool();
await Promise.all(RELAYS.map(async (relay) => await pool.ensureRelay(relay)));
pool.publish(RELAYS, event);