Skip to content

Commit

Permalink
Merge pull request #112 from nostr-jp/sync
Browse files Browse the repository at this point in the history
  • Loading branch information
Hakkadaikon authored Nov 18, 2024
2 parents 793c28e + df467b5 commit d90fc24
Show file tree
Hide file tree
Showing 64 changed files with 2,962 additions and 652 deletions.
25 changes: 12 additions & 13 deletions 01.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,20 @@ NIP-01
```

同一のイベントに対して異なるイベントIDが生成されるような実装の差異を防ぐため、シリアライズを行う際には以下のルールに従わなければならない(MUST):
エンコーディングにはUTF-8を使用するべきだ。
- ホワイトスペースや改行、その他の不必要なフォーマットは出力のJSONに含めてはならない。
- 以下の文字列以外はエスケープせず、そのまま含めるべきだ:
- 改行`0x0A``\n`
- 二重引用符`0x22``\"`
- バックスラッシュ`0x3C``\\`
- バックスラッシュ`0x5C``\\`
- キャリッジリターン`0x0D``\r`
- タブ文字`0x09``\t`
- バックスペース`0x08``\b`
- 改ページ`0x0C``\f`
- エンコーディングにはUTF-8を使用するべきだ。

### タグ

タグはそれぞれ任意長の文字列の配列で、関連していくつかの慣例がある。以下の例を見てみよう。
タグはそれぞれ1以上の文字列の配列で、関連していくつかの慣例がある。以下の例を見てみよう。

```jsonc
{
Expand All @@ -77,9 +77,9 @@ NIP-01

- `e`タグ。イベントを参照するために用いる: `["e", <他のイベントIDの32バイト小文字16進数文字列>, <おすすめのリレーURL、省略可能>]`
- `p`タグ。別のユーザを参照するために用いる: `["p", <pubkeyの32バイト小文字16進数文字列>, <おすすめのリレーURL、省略可能>]`
- `a`タグ。(パラメータ付き・無し)置換可能イベントを参照するために用いる
- パラメータ付き置換可能イベントの場合: `["a", <kind整数>:<pubkeyの32バイト小文字16進数文字列>:<dタグの値>, <おすすめリレーURL、省略可能>]`
- パラメータ無し置換可能イベントの場合: `["a", <kind整数>:<pubkeyの32バイト小文字16進数文字列>:, <おすすめリレーURL、省略可能>]`
- `a`タグ。アドレス指定可能 (addressable) または置換可能 (replaceable) イベントを参照するために用いる
- アドレス指定可能 (addressable) イベントの場合: `["a", <kind整数>:<pubkeyの32バイト小文字16進数文字列>:<dタグの値>, <おすすめリレーURL、省略可能>]`
- 置換可能 (replaceable) イベントの場合: `["a", <kind整数>:<pubkeyの32バイト小文字16進数文字列>:, <おすすめリレーURL、省略可能>]`

慣例として、全ての1文字(英語のアルファベットa-zとA-Zに限る)キーをもつタグは、リレーによってインデクスされることが期待される。これにより、例えば、イベント`"5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"`を参照しているイベントをクエリしたり購読するために、`{"#e": ["5c83da77af1dec6d7289834998ad7aafbd9e2191396d75ec3cc27f5a77226f36"]}`フィルタを使える。

Expand All @@ -92,10 +92,10 @@ Kindはクライアントがイベントやイベントのフィールドをど

実験を容易にし、リレーの実装を柔軟にするため、kindの範囲についての以下のような慣例もある。

- kind`n`が範囲`1000 <= n < 10000`の場合は、イベントは**通常(regular)**で、全てがリレーに保存されることが期待される。
- kind`n`が範囲`1000 <= n < 10000 || 4 <= n < 45 || n == 1 || n == 2`の場合は、イベントは**通常(regular)**で、全てがリレーに保存されることが期待される。
- kind`n`が範囲`10000 <= n < 20000 || n == 0 || n == 3`の場合は、イベントは**置換可能(replaceable)**で、最新のイベントだけがリレーに保持されなければならない(MUST)。また、古いバージョンは破棄してもかまわない(MAY)。
- kind`n`が範囲`20000 <= n < 30000`の場合は、イベントは**一時的(ephemeral)**で、リレーに保存されないことが期待される。
- kind`n`が範囲`30000 <= n < 40000`の場合は、イベントは**パラメータ付き置換可能(parameterized replaceable)**で、`pubkey``kind``d`タグの最初の値の組み合わせについて、最新のイベントのみがリレーに保存されなければならない(MUST)。また、古いバージョンは破棄してかまわない(MAY)。
- kind`n`が範囲`30000 <= n < 40000`の場合は、イベントは**アドレス指定可能 (addressable)**で、`pubkey``kind``d`タグの最初の値の組み合わせについて、最新のイベントのみがリレーに保存されなければならない(MUST)。また、古いバージョンは破棄してかまわない(MAY)。

置換可能イベントが同じタイムスタンプを持っている場合は、最も小さいID(辞書順で最初)のイベントが保持され、他のイベントは破棄されるべきだ。

Expand Down Expand Up @@ -125,13 +125,13 @@ Kindはクライアントがイベントやイベントのフィールドをど
"authors": <a list of lowercase pubkeys, the pubkey of an event must be one of these>,
"kinds": <a list of a kind numbers>,
"#<single-letter (a-zA-Z)>": <a list of tag values, for #e — a list of event ids, for #p — a list of pubkeys, etc.>,
"since": <an integer unix timestamp in seconds, events must be newer than this to pass>,
"until": <an integer unix timestamp in seconds, events must be older than this to pass>,
"since": <an integer unix timestamp in seconds. Events must have a created_at >= to this to pass>,
"until": <an integer unix timestamp in seconds. Events must have a created_at <= to this to pass>,
"limit": <maximum number of events relays SHOULD return in the initial query>
}
```

`REQ`メッセージを受信すると、リレーは内部データベースに問い合わせてフィルターにマッチするイベントを返し、そのフィルターを保存しておいて、以降に受信した全てのイベントをWebSocketがクローズされるまで同じWebSocketに送信すべきだ(SHOULD)。同一の`<購読ID>`を持つ`CLOSE`イベントを受信するか、同一の`<購読ID>`を使って新たな`REQ`が送信されると、リレーは既存の購読を更新しなければならない(MUST)。
`REQ`メッセージを受信すると、リレーはフィルターにマッチするイベントを返す。新しく受信したイベントは接続が閉じられるか、同じ`<subscripttion_id>``CLOSE`イベントが受信されるか、同じ`<subscription_id>` を使用して新しい`REQ`が送信されるまで、同じWebSocketに送信されるべきだ(SHOULD)。(この場合、新しい購読が作成され、古い購読が置き換えられる。)

リストをとるフィルター属性(`ids``authors``kind``#e`のようなタグフィルタ)は、1つ以上の要素を持つJSON配列である。その条件がマッチしたとみなされるためには、配列の値のうち少なくとも1つがイベントの関連するフィールドと一致しなければならない。`authors``kind`のようなスカラーのイベント属性の場合は、イベントの属性値がフィルターのリストに含まれなければならない。`#e`などのタグ属性のように、イベントが複数の値を持ちうる場合は、イベントとフィルタの条件値が少なくとも1つの共通する要素を持たなければならない。

Expand All @@ -143,7 +143,7 @@ Kindはクライアントがイベントやイベントのフィールドをど

1つの`REQ`メッセージに複数のフィルタを含むことができる。この場合、いずれかのフィルタにマッチするイベントが返される。つまり、複数のフィルタは`||`条件として解釈される。

フィルタの`limit`プロパティは、初期クエリにのみ影響を及ぼし、それ以降は無視されなければならない(MUST)。`limit: n`が存在する場合、初期クエリでは最新の`n`イベントが`created_at`順に返されることが想定される。`limit`の指定よりも少ないイベントを返すことは問題ない。しかし、クライアントに対して不必要に負荷を与えることを避けるため、リレーは要求されたよりも(はるかに)多くのイベントを返すことがないよう期待される。
フィルタの`limit`プロパティは、初期クエリにのみ影響を及ぼし、それ以降は無視されなければならない(MUST)。`limit: n`が存在する場合、初期クエリでは最新の`n`イベントが`created_at`順に返されることが想定される。`新しいイベントが最初に表示され、同時刻の場合はidが最も小さい (辞書式順序で最初の) イベントが最初に表示されるべきである。limit`の指定よりも少ないイベントを返すことは問題ない。しかし、クライアントに対して不必要に負荷を与えることを避けるため、リレーは要求されたよりも(はるかに)多くのイベントを返すことがないよう期待される。

### リレーからクライアントへ: イベントの送信と通知

Expand All @@ -169,7 +169,6 @@ Kindはクライアントがイベントやイベントのフィールドをど
* `["OK", "b1a649ebe8...", false, "pow: difficulty 26 is less than 30"]` pow: 難易度26は30よりも小さい
* `["OK", "b1a649ebe8...", false, "error: could not connect to the database"]` エラー: データベースに接続できなかった
- `CLOSED`メッセージは、リレーが`REQ`の処理を拒否するときに、その応答として送信されなければならない (MUST) 。また、クライアントが切断したり`CLOSE`を送信する前に、リレーの側から購読を強制終了する場合にも送信される。このメッセージは機械可読なプレフィクスと人間可読なメッセージを含んだ`OK`メッセージと同じパターンを使用する。例は以下の通り:
* `["CLOSED", "sub1", "duplicate: sub1 already opened"]` 重複: sub1はすでに開かれている
* `["CLOSED", "sub1", "unsupported: filter contains unknown elements"]` サポートされていない: フィルターに不明な要素が含まれている
* `["CLOSED", "sub1", "error: could not connect to the database"]` エラー: データベースに接続できなかった
* `["CLOSED", "sub1", "error: shutting down idle subscription"]` エラー: アイドル状態の購読をシャットダウン
Expand Down
8 changes: 5 additions & 3 deletions 02.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ NIP-02

「フォローリスト」を意味するkind `3`の特別なイベントは、フォローしている/既知のプロフィールごとの`p`タグのリストを持つものとして定義される。

タグの個々の要素は、プロフィールの鍵・その鍵からのイベントを発見できるリレーのURL (必要なければ空文字列で設定可能) ・そのプロフィールのローカル名 (あるいは「愛称」) (空文字列が設定されるか、提供されないようできる) を含むべきで、つまり`["p", <32-bytes hex key>, <main relay URL>, <petname>]`である。`content`は何でもかまわないが、無視されるべきである。
タグの個々の要素は、プロフィールの鍵・その鍵からのイベントを発見できるリレーのURL (必要なければ空文字列で設定可能) ・そのプロフィールのローカル名 (あるいは「愛称」) (空文字列が設定されるか、提供されないようできる) を含むべきで、つまり`["p", <32-bytes hex key>, <main relay URL>, <petname>]`である。

`.content`は使用されない。

例:

```json
```jsonc
{
"kind": 3,
"tags": [
Expand All @@ -21,7 +23,7 @@ NIP-02
["p", "612ae..e610f", "ws://carolrelay.com/ws", "carol"]
],
"content": "",
...other fields
// other fields...
}
```

Expand Down
2 changes: 1 addition & 1 deletion 04.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
> __Warning__ `unrecommended`: deprecated in favor of [NIP-44](44.md)
> __Warning__ `unrecommended`: deprecated in favor of [NIP-17](17.md)
NIP-04
======
Expand Down
25 changes: 15 additions & 10 deletions 05.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ Nostr鍵をDNSベースのインターネット識別子に結びつける

`final` `optional`

kind `0` (`metadata`)には[インターネット識別子](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (eメールのようなアドレス) を値として`"nip05"`というキーを指定できる。"インターネット識別子"に対する多種多様な仕様のリンクがあるが、NIP-05は`<local-part>`部分が`a-z0-9-_.`で大文字と小文字を区別しないことを前提としている。
kind `0` (`user metadata`)には[インターネット識別子](https://datatracker.ietf.org/doc/html/rfc5322#section-3.4.1) (eメールのようなアドレス) を値として`"nip05"`というキーを指定できる。"インターネット識別子"に対する多種多様な仕様のリンクがあるが、NIP-05は`<local-part>`部分が`a-z0-9-_.`で大文字と小文字を区別しないことを前提としている。

クライアントは識別子を`<local-part>``<domain>`に分けた上でそれらの値で`https://<domain>/.well-known/nostr.json?name=<local-part>`にGET要求を行う。

結果として、16進数で表される公開鍵に対応した`"names"`キーを持つ、JSONドキュメントオブジェクトが返されなければならない。指定された`<name>`の公開鍵が`metadata`イベントの`pubkey`と一致する場合、クライアントは与えられた公開鍵が実際にその識別子で照会できると結論付ける。
結果として、16進数で表される公開鍵に対応した`"names"`キーを持つ、JSONドキュメントオブジェクトが返されなければならない。指定された`<name>`の公開鍵が`user metadata`イベントの`pubkey`と一致する場合、クライアントは与えられた公開鍵が実際にその識別子で照会できると結論付ける。

###


クライアントが下記のようなイベントを見た時。

```json
```jsonc
{
"pubkey": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9",
"kind": 0,
"content": "{\"name\": \"bob\", \"nip05\": \"[email protected]\"}"
...
// other fields...
}
```

Expand All @@ -34,7 +34,7 @@ kind `0` (`metadata`)には[インターネット識別子](https://datatracker.
"bob": "b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9"
}
}
````
```

あるいは、**推奨**される`"relays"`属性が追加される場合は次の通り。

Expand All @@ -47,7 +47,7 @@ kind `0` (`metadata`)には[インターネット識別子](https://datatracker.
"b0635d6a9851d3aed0cd6c495b282167acf761729078d975fc341b22650b07b9": [ "wss://relay.example.com", "wss://relay2.example.com" ]
}
}
````
```

上記の例のように公開鍵が`"names"`で与えられたものと一致する場合、関連付けが正しいことを意味し、`"nip05"`識別子は有効なものとして表示できる。

Expand All @@ -59,6 +59,15 @@ kind `0` (`metadata`)には[インターネット識別子](https://datatracker.

## メモ

### 識別する、検証はしない

NIP-05はユーザーを_検証_するためではなく、連絡先の交換や検索を容易とするために_識別_することを目的としている。
例外は有名なドメインを所有する (企業等) あるいは関係する人 (プロジェクト等) であり、NIP-05をそのドメインとの関係、ひいてはその背後にある組織との関係を証明するものとして利用でき、信用の要素を得ることができる。

### ユーザー発見実装の提案

クライアントはこれをユーザーが他のプロフィールの検索で使えるようにできる。クライアントが検索ボックスなどを持っている場合、そこに"[email protected]"と入力でき、クライアントはそれを識別して適切なクエリで公開鍵を取得し、ユーザーに提案できる。

### クライアントはNIP-05アドレスでなく常に公開鍵をフォローする必要がある。

例えば、もし公開鍵`abc…def`をもった`[email protected]`を見つけて、ユーザーがそのプロフィールをフォローすることにした際、クライアントは`[email protected]`ではなく`abc…def`を第一参照先にする必要がある。何らかの理由で、将来`https://bob.com/.well-known/nostr.json?name=bob`が公開鍵`1d2...e3f`を返すようになった場合でもクライアントはフォロー済みユーザーリストで`abc...def`を置き換えてはならない。但し、そのユーザーの”[email protected]”は無効な`”nip05”`プロパティとなるため、表示を止めるべきである。
Expand All @@ -67,10 +76,6 @@ kind `0` (`metadata`)には[インターネット識別子](https://datatracker.

鍵は16進数の形式で返される必要がある。NIP-19`npub`形式はこのNIPではなく、クライアントUIでの表示にのみ使用される。

### ユーザー発見実装の提案

クライアントはこれをユーザーが他のプロフィールの検索で使えるようにできる。クライアントが検索ボックスなどを持っている場合、そこに"[email protected]"と入力でき、クライアントはそれを識別して適切なクエリで公開鍵を取得し、ユーザーに提案できる。

### ドメインのみを識別子として表示する

クライアントは`_@domain`識別子を”ルート”識別子として扱い、`<domain>`のみを表示できる。例えば、Bobが`bob.com`を所有している場合、`[email protected]`のような冗長な識別子を望まないかもしれない。代わりに、`_bob.com`を使用してNostrクライアントが如何なる目的でも単に`bob.com`として扱い、表示することを期待できる。
Expand Down
4 changes: 4 additions & 0 deletions 07.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ async window.nostr.nip44.encrypt(pubkey, plaintext): string // returns ciphertex
async window.nostr.nip44.decrypt(pubkey, ciphertext): string // takes ciphertext as specified in nip-44
```

### 拡張機能の作成者への推奨事項
ページの読み込み時にnostrクライアントが`window.nostr`を利用できるようにするには、ChromiumおよびFirefoxの拡張機能の作成者は、拡張機能のマニフェストで`"run_at": "document_end"`を指定してスクリプトをロードする必要がある。


### 実装

https://github.com/aljazceru/awesome-nostr#nip-07-browser-extensions を参照する。
Loading

0 comments on commit d90fc24

Please sign in to comment.