3.8 KiB
transit
a combined publish-subscribe and post office protocol and implementation for HTTP based decentralized messaging
tl;dr
fragmentation of user identity is a huge problem in web3 app development, every dApp is tied to one chain and the cost of users migrating to another platform is high.
the same problem exists also with centralized social networks, you can't just go to another venue and join the conversation, you have to have a whole new identity and as well as the problems that this enables malicious use, it also makes any efforts to build borderless social network communications applications basically impossible.
nostr...
nostr is a project that has paved the way for a mechanism by which users identities work seamlessly across multiple servers, mostly interoperable, but it is plagued with its association with Bitcoin and Jack Dorsey and a faux decentralised committee of grant giving organisations and people defining protocol specifications that are not well-thought-out and constantly changing, and worst, for no reason at all, it uses websockets, which makes implementation too complex and specialised for wide developer adoption.
HTTP API and industry standard cryptography
Instead of using websockets, transit uses standard HTTP REST API for messaging, authentication for access control is integrated into headers. It does retain the use of SHA256 and secp256k1 X-only (taproot/BIP-340) signatures, however, because support for ECDH with the popular ed25519 elliptic curve is not good for Go. However, the shared secrets the secp256k1 library generates are used with ChaCha20-Poly1305.
By using these well-supported, well understood protocol elements, we eliminate the friction for most web developers to build apps that interact with transit relays and enable the building of a multitude of different kinds of collaborative messaging and data storage applications with a single unified toolkit.
Data Structure Design
The primary data structure is designed to wrap the message within the authenticated form so that verifying the event is just a matter of extracting the message with a simple scan of the text to find ,"id": as the end of the embedded event data starting after the first parenthesis, and then hashing that to check the Id and then verify the signature. This is done to simplify the verification of the event for client developers. For this reason also, the order of the event must be exactly as follows:
{
"pubkey": "pbzr68pRvnkMRLHRfvsbf6l_Zg5bd0rX9L-NFOpeiAU",
"content": "this is some content\n\nwith multiple lines\n\nto show how it encodes\n\n#winning",
"kind": "forum/reply",
"mimetype":"text/asciidoc",
"tags":[
["root","sS9QdR6lGY5WCpVOcuL6hj2WsciqNxMIeiagFxjj3T8"],
["parent","yA430Df4y-0XXTwWDLdDfSVFLDhh9dcna37kJQ4-x9A"],
["event","oI4QOM4xwFfbkmIdYtClmxKou6ercZkejYa9n8eh8hA"],
["user","L5EIWco9mSu0hkwkOqE97uOe7QyUISOxy5gubC-pB2g"],
["hashtag","winning"],
["url","http://example.com"]
]
}
Note that here is shown the pretty printed form, it must be processed for verification in minified form as sent on the wire.
Also note that the "content" field is escaped with the simple escaping scheme used with nostr which only escapes control characters with the single letter type, any other special characters must be in standard utf \uXXXX form. Only change these unicode escape characters for presentation, in JSON form the process of unescaping and escaping must be reversible.
Signed Form of Event
Because we stipulate a consistent structure to the event JSON, it is not necessary to include the event Id in the wire encoded message. The receiver can then slice the message up to derive the Id to use with the public key to verify the event.