Nostred: Difference between revisions

From Traxel Wiki
Jump to navigation Jump to search
No edit summary
 
(36 intermediate revisions by the same user not shown)
Line 1: Line 1:
[[Category:Nostr]]
[[Category:Nostr]]
= Overview =
= Overview =
Nostred is a topical threaded messaging system that treats centralized censorship as damage and routes around it. Decentralized censorship (aka: popularity, zeitgeist) is just a thing that happens. Governments, corporations, oligarchs, and madmen attempt to influence the direction of decentralized censorship.
= Links =
* NIP-10, Threaded Discussions: https://github.com/nostr-protocol/nips/blob/master/10.md
* NIP-72, Reddit Style Communities: https://github.com/nostr-protocol/nips/blob/master/72.md
** Combining NIP-72 with an automod filter in Strfry should be very doable.
*** Is it a top level post?
**** Is the signer top-level whitelisted?
**** Is the signer top-level blacklisted?
**** Do I have history or other to trust signer for top level?
*** Is it a reply? Is the signer reply-approved?
**** Is the signer reply whitelisted?
**** Is the signer reply blacklisted?
**** Do I have history or other to trust signer for reply?
* [[NostredCommentStructure]]
= Examples =
== Community Description ==
<syntaxhighlight lang="json">
{
  "id": "<32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>",
  "pubkey": "<32-bytes lowercase hex-encoded public key of the event creator>",
  "created_at": <Unix timestamp in seconds>,
  "kind": 34550,
  "tags": [
    ["d", "<Community name>"],
    ["description", "<Community description>"],
    ["image", "<Community image url>", "<Width>x<Height>"],
    //.. other tags relevant to defining the community
    // moderators
    ["p", "<32-bytes hex of a pubkey1>", "<optional recommended relay URL>", "moderator"],
    ["p", "<32-bytes hex of a pubkey2>", "<optional recommended relay URL>", "moderator"],
    ["p", "<32-bytes hex of a pubkey3>", "<optional recommended relay URL>", "moderator"],
    // relays used by the community (w/optional marker)
    ["relay", "<relay hosting author kind 0>", "author"],
    ["relay", "<relay where to send and receive requests>", "requests"],
    ["relay", "<relay where to send and receive approvals>", "approvals"],
    ["relay", "<relay where to post requests to and fetch approvals from>"]
  ]
}
</syntaxhighlight>
== New Post Request ==
Satisfies two NIPs:
* https://github.com/nostr-protocol/nips/blob/master/10.md#marked-e-tags-preferred
* https://github.com/nostr-protocol/nips/blob/master/72.md#new-post-request
<syntaxhighlight lang="json">
{
  "id": "<32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>",
  "pubkey": "<32-bytes lowercase hex-encoded public key of the event creator>",
  "created_at": <Unix timestamp in seconds>,
  "kind": 1,
  "tags": [
    ["a", "34550:<Community event author pubkey>:<d-identifier of the community>", "<Optional relay url>"],
    ["e", "<event-id>", "<relay-url>", "root"], // required for all replies, identifies the root post
    ["e", "<event-id>", "<relay-url>", "reply"], // optional, if this is a reply to a reply
  ],
  "content": "<My content>"
}
</syntaxhighlight>
=== Testing ===
<pre>
$ python bob_test.py send -r ws://localhost:7777 --content "Nostred" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]]'
5b8440d62761bab91c36708a6143aa51a725a1f1fd320a5d580ae818455d1906
nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw
$ python bob_test.py get -r ws://localhost:7777 nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw
{"id":"5b8440d62761bab91c36708a6143aa51a725a1f1fd320a5d580ae818455d1906","pubkey":"7cbf8abdcade4d216ef8cd2b33ba2256799d81ae0a2e88a7df6187c98fcd433b","created_at":1696902240,"kind":1,"tags":[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]],"content":"Nostred","sig":"cbe2434cf9d8790df669afbe0bb8a435999bef4539fa6a1c725fb0bda9073e97b1531bdedbcca7523fa5a375e4f472671047cde51c4870041e7971c6d218aecd"}
5b8440d62761bab91c36708a6143aa51a725a1f1fd320a5d580ae818455d1906
nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw
$ python bob_test.py send -r ws://localhost:7777 --content "Nostred" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e", "nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw", "ws://localhost:7777", "root"]]'
18334e45d9493d754016147a3546c340b6fca58f1695611197d3311f5dcc1312
nevent1qqspsv6wghv5j0t4gqtpg734gmp5pdhu5k83d9tpzxtaxvglthxpxyspzdmhxw309akx7cmpd35x7um58gmnwdeh5erhwd
$ python bob_test.py send -r ws://localhost:7777 --content "Nostred" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e", "nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw", "ws://localhost:7777", "root"],["e", "nevent1qqspsv6wghv5j0t4gqtpg734gmp5pdhu5k83d9tpzxtaxvglthxpxyspzdmhxw309akx7cmpd35x7um58gmnwdeh5erhwd", "ws://localhost:7777", "reply"]]'
97136773dd2d482b71684085c6a33ede5e85f3cd410242adb3fb730c201a1bb1
nevent1qqsfwym8w0wj6jptw95yppwx5vlduh5970x5zqjz4kelkucvyqdphvgpzdmhxw309akx7cmpd35x7um58gmnwdeh9w968t
$ python bob_test.py get -r ws://localhost:7777 nevent1qqsfwym8w0wj6jptw95yppwx5vlduh5970x5zqjz4kelkucvyqdphvgpzdmhxw309akx7cmpd35x7um58gmnwdeh9w968t
</pre>
The replies were actually failing with the following message in the Strfry log. Need to look at why the client isn't reporting the failure, and where it's getting that event ID from.
<pre>
2023-10-10 02:05:53.063 (85038.540s) [Websocket      ]INFO| [20] Connect from 127.0.0.1 compression=Y sliding=Y
2023-10-10 02:05:53.125 (85038.602s) [Ingester 2      ]INFO| Rejected invalid event: uneven size input to from_hex
2023-10-10 02:05:53.171 (85038.648s) [Websocket      ]INFO| [20] Disconnect from 127.0.0.1 (1000/) UP: 120b (7.5% compressed) DN: 625b (30.7% compressed)
</pre>
Looks like Strfry does not like unpadded hex, which I'm guessing was sent in by aionostr:
<pre>
strfry$ more golpe/external/hoytech-cpp/hoytech/hex.h
...
    if ((input.length() % 2) != 0) {
        if (!allowUnevenSize) throw hoytech::error("uneven size input to from_hex");
        std::string padded; // does a copy if given non-even number of hex digits
        padded += '0';
        padded += input;
        input = padded;
    }
...
</pre>
AHA! It's the hex message ID I have to send back, not the base 32 nevent id:
<pre>
$ python bob_test.py send -r ws://localhost:7777 --content "Nostred2" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]]'
3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29
nevent1qqsr4dvezkqmkgltu5dzfyvvs64aty2ulmr8yf0v0k9ew4ptsnaxu2gpzdmhxw309akx7cmpd35x7um58gmnwdehy7k9rs
$ python bob_test.py get -r ws://localhost:7777 nevent1qqsr4dvezkqmkgltu5dzfyvvs64aty2ulmr8yf0v0k9ew4ptsnaxu2gpzdmhxw309akx7cmpd35x7um58gmnwdehy7k9rs
{"id":"3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29","pubkey":"7cbf8abdcade4d216ef8cd2b33ba2256799d81ae0a2e88a7df6187c98fcd433b","created_at":1696905392,"kind":1,"tags":[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]],"content":"Nostred2","sig":"eb148e6804e4e1b896adfd5c7e9c399d8e029a5010ee35547ab9eaab356d8f0524a6da99a15162463c3a1205062621da4b3001422b9e6ba7220c67d51f1dc474"}
$ python bob_test.py send -r ws://localhost:7777 --content "Grumble" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e", "3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29", ""]]'
3346dce2124ae5cf674a0a0d427543a4d35fa592fcdf0dd078cff47806df432d
nevent1qqsrx3kuugfy4ew0va9q5r2zw4p6f56l5kf0ehcd6puvlarcqm05xtgpzdmhxw309akx7cmpd35x7um58gmnwdeh79mhys
$ python bob_test.py get -r ws://localhost:7777 nevent1qqsrx3kuugfy4ew0va9q5r2zw4p6f56l5kf0ehcd6puvlarcqm05xtgpzdmhxw309akx7cmpd35x7um58gmnwdeh79mhys
{"id":"3346dce2124ae5cf674a0a0d427543a4d35fa592fcdf0dd078cff47806df432d","pubkey":"7cbf8abdcade4d216ef8cd2b33ba2256799d81ae0a2e88a7df6187c98fcd433b","created_at":1696905458,"kind":1,"tags":[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e","3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29",""]],"content":"Grumble","sig":"de9f6b5737e4d97f270b7331d780c0c12ce3fe09f0804ae03bfe1025284100b3158f07a20199661e95242b007c6c7b2d1d556008852ef714d2d29795446e988e"}
</pre>
I don't love it. How do I get that hex ID on the client side? I'm guessing it's generated on the server side, cuz why would the server let clients generate their own message IDs? But I could be wrong, and maybe Strfry returns the message ID in the response and AIONostr just doesn't display it (or doesn't display it as hex).
Yeah - or I could read the line before the base32 NIP-19 form of the id. You know, the previous line which is suspiciously hex looking. :D
== Post Approval ==
= Story =
Using Cyberpunk 2077 as a rough framing device. Actors are not meant to be exact copies from the game, but to act as rough parallels.
Using Cyberpunk 2077 as a rough framing device. Actors are not meant to be exact copies from the game, but to act as rough parallels.
Imagine a world in which amoral corporations and their oligarchic founders have extreme influence over government. People have become disenfranchised and some have begun to radicalize. Those people want to use Nostred for messaging to advance what they believe is in the best interests of society.
Nostred is a topical threaded messaging system that treats centralized censorship as damage and routes around it. Decentralized censorship (aka: popularity, zeitgeist) is just a thing that happens. Governments, corporations, oligarchs, and madmen attempt to influence the direction of decentralized censorship.
== People ==
== People ==
=== V ===
=== V ===
Line 34: Line 158:


Judy opposes because riots might get people hurt. Arasaka enlists Militech to suppress the messaging.
Judy opposes because riots might get people hurt. Arasaka enlists Militech to suppress the messaging.
=== Arasaka Suppression ===
* Arasaka starts by finding unlawful material carried by the relays, and asking Militech to shut them down.
* Later, Arasaka plants copyrighted material, when the relays stop doing illegal things.
* Arasaka gets speech that incites violence ruled illegal and just cause for relay takedown.
Are these things illegal? The story has to be credible. Find the actual legal status.
* Section 230: https://en.wikipedia.org/wiki/Section_230
** Argument for Duty of Care: https://hbr.org/2021/08/its-time-to-update-section-230
== Takahara Assassination ==
== Takahara Assassination ==
Takahara wants to knock off a VP and his cronies. Crowd-sources the solution and enlists actors via Nostr.
Takahara wants to knock off a VP and his cronies. Crowd-sources the solution and enlists actors via Nostr.


Arasaka enlists Militech to detect, unmask, and arrest Takahara.
Arasaka enlists Militech to detect, unmask, and arrest Takahara.

Latest revision as of 21:50, 12 October 2023

Overview

Nostred is a topical threaded messaging system that treats centralized censorship as damage and routes around it. Decentralized censorship (aka: popularity, zeitgeist) is just a thing that happens. Governments, corporations, oligarchs, and madmen attempt to influence the direction of decentralized censorship.

Links

Examples

Community Description

{
  "id": "<32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>",
  "pubkey": "<32-bytes lowercase hex-encoded public key of the event creator>",
  "created_at": <Unix timestamp in seconds>,
  "kind": 34550,
  "tags": [
    ["d", "<Community name>"],
    ["description", "<Community description>"],
    ["image", "<Community image url>", "<Width>x<Height>"],

    //.. other tags relevant to defining the community

    // moderators
    ["p", "<32-bytes hex of a pubkey1>", "<optional recommended relay URL>", "moderator"],
    ["p", "<32-bytes hex of a pubkey2>", "<optional recommended relay URL>", "moderator"],
    ["p", "<32-bytes hex of a pubkey3>", "<optional recommended relay URL>", "moderator"],

    // relays used by the community (w/optional marker)
    ["relay", "<relay hosting author kind 0>", "author"],
    ["relay", "<relay where to send and receive requests>", "requests"],
    ["relay", "<relay where to send and receive approvals>", "approvals"],
    ["relay", "<relay where to post requests to and fetch approvals from>"]
  ]
}

New Post Request

Satisfies two NIPs:

{
  "id": "<32-bytes lowercase hex-encoded SHA-256 of the the serialized event data>",
  "pubkey": "<32-bytes lowercase hex-encoded public key of the event creator>",
  "created_at": <Unix timestamp in seconds>,
  "kind": 1,
  "tags": [
    ["a", "34550:<Community event author pubkey>:<d-identifier of the community>", "<Optional relay url>"],
    ["e", "<event-id>", "<relay-url>", "root"], // required for all replies, identifies the root post
    ["e", "<event-id>", "<relay-url>", "reply"], // optional, if this is a reply to a reply
  ],
  "content": "<My content>"
}

Testing

$ python bob_test.py send -r ws://localhost:7777 --content "Nostred" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]]' 
5b8440d62761bab91c36708a6143aa51a725a1f1fd320a5d580ae818455d1906
nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw
$ python bob_test.py get -r ws://localhost:7777 nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw
{"id":"5b8440d62761bab91c36708a6143aa51a725a1f1fd320a5d580ae818455d1906","pubkey":"7cbf8abdcade4d216ef8cd2b33ba2256799d81ae0a2e88a7df6187c98fcd433b","created_at":1696902240,"kind":1,"tags":[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]],"content":"Nostred","sig":"cbe2434cf9d8790df669afbe0bb8a435999bef4539fa6a1c725fb0bda9073e97b1531bdedbcca7523fa5a375e4f472671047cde51c4870041e7971c6d218aecd"}
5b8440d62761bab91c36708a6143aa51a725a1f1fd320a5d580ae818455d1906
nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw
$ python bob_test.py send -r ws://localhost:7777 --content "Nostred" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e", "nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw", "ws://localhost:7777", "root"]]'
18334e45d9493d754016147a3546c340b6fca58f1695611197d3311f5dcc1312
nevent1qqspsv6wghv5j0t4gqtpg734gmp5pdhu5k83d9tpzxtaxvglthxpxyspzdmhxw309akx7cmpd35x7um58gmnwdeh5erhwd
$ python bob_test.py send -r ws://localhost:7777 --content "Nostred" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e", "nevent1qqs9hpzq6cnkrw4ersm8pznpgw49rfe958cl6vs2t4vq46qcg4w3jpspzdmhxw309akx7cmpd35x7um58gmnwdehzt4mtw", "ws://localhost:7777", "root"],["e", "nevent1qqspsv6wghv5j0t4gqtpg734gmp5pdhu5k83d9tpzxtaxvglthxpxyspzdmhxw309akx7cmpd35x7um58gmnwdeh5erhwd", "ws://localhost:7777", "reply"]]'
97136773dd2d482b71684085c6a33ede5e85f3cd410242adb3fb730c201a1bb1
nevent1qqsfwym8w0wj6jptw95yppwx5vlduh5970x5zqjz4kelkucvyqdphvgpzdmhxw309akx7cmpd35x7um58gmnwdeh9w968t
$ python bob_test.py get -r ws://localhost:7777 nevent1qqsfwym8w0wj6jptw95yppwx5vlduh5970x5zqjz4kelkucvyqdphvgpzdmhxw309akx7cmpd35x7um58gmnwdeh9w968t

The replies were actually failing with the following message in the Strfry log. Need to look at why the client isn't reporting the failure, and where it's getting that event ID from.

2023-10-10 02:05:53.063 (85038.540s) [Websocket       ]INFO| [20] Connect from 127.0.0.1 compression=Y sliding=Y
2023-10-10 02:05:53.125 (85038.602s) [Ingester 2      ]INFO| Rejected invalid event: uneven size input to from_hex
2023-10-10 02:05:53.171 (85038.648s) [Websocket       ]INFO| [20] Disconnect from 127.0.0.1 (1000/) UP: 120b (7.5% compressed) DN: 625b (30.7% compressed)

Looks like Strfry does not like unpadded hex, which I'm guessing was sent in by aionostr:

strfry$ more golpe/external/hoytech-cpp/hoytech/hex.h
...
    if ((input.length() % 2) != 0) {
        if (!allowUnevenSize) throw hoytech::error("uneven size input to from_hex");
        std::string padded; // does a copy if given non-even number of hex digits
        padded += '0';
        padded += input;
        input = padded;
    }
...

AHA! It's the hex message ID I have to send back, not the base 32 nevent id:

$ python bob_test.py send -r ws://localhost:7777 --content "Nostred2" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]]' 
3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29
nevent1qqsr4dvezkqmkgltu5dzfyvvs64aty2ulmr8yf0v0k9ew4ptsnaxu2gpzdmhxw309akx7cmpd35x7um58gmnwdehy7k9rs
$ python bob_test.py get -r ws://localhost:7777 nevent1qqsr4dvezkqmkgltu5dzfyvvs64aty2ulmr8yf0v0k9ew4ptsnaxu2gpzdmhxw309akx7cmpd35x7um58gmnwdehy7k9rs
{"id":"3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29","pubkey":"7cbf8abdcade4d216ef8cd2b33ba2256799d81ae0a2e88a7df6187c98fcd433b","created_at":1696905392,"kind":1,"tags":[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"]],"content":"Nostred2","sig":"eb148e6804e4e1b896adfd5c7e9c399d8e029a5010ee35547ab9eaab356d8f0524a6da99a15162463c3a1205062621da4b3001422b9e6ba7220c67d51f1dc474"}
$ python bob_test.py send -r ws://localhost:7777 --content "Grumble" --kind 1 --private-key nsec1dgg7d6e0g2484twl9ygntc24ueehm44frrc8rc93vcvun04gmp9qgufd4g --tags '[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e", "3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29", ""]]'
3346dce2124ae5cf674a0a0d427543a4d35fa592fcdf0dd078cff47806df432d
nevent1qqsrx3kuugfy4ew0va9q5r2zw4p6f56l5kf0ehcd6puvlarcqm05xtgpzdmhxw309akx7cmpd35x7um58gmnwdeh79mhys
$ python bob_test.py get -r ws://localhost:7777 nevent1qqsrx3kuugfy4ew0va9q5r2zw4p6f56l5kf0ehcd6puvlarcqm05xtgpzdmhxw309akx7cmpd35x7um58gmnwdeh79mhys
{"id":"3346dce2124ae5cf674a0a0d427543a4d35fa592fcdf0dd078cff47806df432d","pubkey":"7cbf8abdcade4d216ef8cd2b33ba2256799d81ae0a2e88a7df6187c98fcd433b","created_at":1696905458,"kind":1,"tags":[["a","34550:npub10jlc40w2mexjzmhce54n8w3z2euemqdwpghg3f7lvxrunr7dgvasm0nurp:Nostred","ws://localhost:7777"],["e","3ab5991581bb23ebe51a24918c86abd5915cfec67225ec7d8b97542b84fa6e29",""]],"content":"Grumble","sig":"de9f6b5737e4d97f270b7331d780c0c12ce3fe09f0804ae03bfe1025284100b3158f07a20199661e95242b007c6c7b2d1d556008852ef714d2d29795446e988e"}

I don't love it. How do I get that hex ID on the client side? I'm guessing it's generated on the server side, cuz why would the server let clients generate their own message IDs? But I could be wrong, and maybe Strfry returns the message ID in the response and AIONostr just doesn't display it (or doesn't display it as hex).

Yeah - or I could read the line before the base32 NIP-19 form of the id. You know, the previous line which is suspiciously hex looking. :D

Post Approval

Story

Using Cyberpunk 2077 as a rough framing device. Actors are not meant to be exact copies from the game, but to act as rough parallels.

Imagine a world in which amoral corporations and their oligarchic founders have extreme influence over government. People have become disenfranchised and some have begun to radicalize. Those people want to use Nostred for messaging to advance what they believe is in the best interests of society.

Nostred is a topical threaded messaging system that treats centralized censorship as damage and routes around it. Decentralized censorship (aka: popularity, zeitgeist) is just a thing that happens. Governments, corporations, oligarchs, and madmen attempt to influence the direction of decentralized censorship.

People

V

The object of everyone's machinations. V has no axe, a priori, to grind. Everyone else is trying to present, suppress, or influence information that V sees to get her to act as they see fit.

Punchin' Judy

Neutral good humanist. Wants everyone to be happy. Sees the best in people. Does not trust Arasaka (nor, by extension, Militech).

Johnny Silverhand

Chaotic good. Justice warrior with an emphasis on "warrior". Asymmetric urban warfare specialist.

Takahara

Lawful good. Believes the system would be good if it weren't for the few baddies in positions of power. Assassin.

Wakako

Chaotic neutral. Does for Wakako.

Orgs

Arasaka

Amoral corporation, only cares about money and power. Law is a constraint that must be worked around or manipulated - or in the worst possible case, followed.

Pacifica

Collective of counter-culture that is obsessed with money and power. Basically Arasaka, but Militech doesn't like them.

The Coyotes

Collective of counter-culture that is benevolent. Works against the big bads (Arasaka and, by extension, often Militech).

Militech

Abstract representation of government force. Often aligns with Arasaka, shot through with people of various conflicted interests; corrupt or idealistic, malevolent or benevolent, psychotic or rational, &c.

Fixers

Not truly an org, but a tag for the collection of indies who are just in it for the money.

Conflict

Arasaka Versus Society

Arasaka wants to control reality for Arasaka's interests. Uses law and influence to manipulate perception of reality.

Militech Versus Society

Militech wants to control society for good, with good defined in occasionally dystopian ways. Creates and enforces law for the benefit of those it (mis)perceives as lawful.

Stories

Silverhand Rabble Rousing

Johnny incites people to go to a flash-mob street performance that will turn into a riot against Arasaka. Messaging via Nostr.

Judy opposes because riots might get people hurt. Arasaka enlists Militech to suppress the messaging.

Arasaka Suppression

  • Arasaka starts by finding unlawful material carried by the relays, and asking Militech to shut them down.
  • Later, Arasaka plants copyrighted material, when the relays stop doing illegal things.
  • Arasaka gets speech that incites violence ruled illegal and just cause for relay takedown.

Are these things illegal? The story has to be credible. Find the actual legal status.

Takahara Assassination

Takahara wants to knock off a VP and his cronies. Crowd-sources the solution and enlists actors via Nostr.

Arasaka enlists Militech to detect, unmask, and arrest Takahara.