Hey everyone! First shortcut of this new season. Sorry for the delay,
I was playing with another project but now is the time to code for
Erlang Punch and nostr I did only few small modification during the
past three months. I merged bech32 module (we'll see that in another
shortcut) and did some cleanup but the project did not change a
lot. At least, we are still stuck on the same issues. Okay, let's
do that!
We were working on nip/05, I think had something that work, but we
will need to check that. Another project could be cool, something we
were talking on for many months: creating the message router. Oh!
I remember now! The link between nip/05 and the database was not
done. Do I want to work on that right now? Not sure. I don't even
remember how this part is working. Let start our pomodoro session.
No more talk ;)
Okay! We need a way to list active clients but it leads to...
database, in particular mnesia. Well, I feel hot to do some
mnesia! :)
So; first pomodoro done. I only updated some documentation and
started to play with mnesia. I don't really know how to deal
with the connection at this time. In fact, if we are starting
to use mnesia... Perhaps we should use it everywhere. I should
dissociate clients and users.
A client is an active connection to a server, and we should only have
one perhaps more if more users need to connect on it.
An user is using a client (so the connection) to receive and share
their information. In this case, we should have something like that:
1. a new client is started, a client abstracts the connection
between an user and the server.
2. a new user want to use the connection/client, then it will share
the same connection if it already exists or create it if not
present.
3. It become an active user.
Let works on the second part.
== 2023-09-05: Shortcut_24/02
Okay! That's the last one for tonight. It's hot out there, and it's
hard to think with this kind of weather. Adding mnesia is not a small
task and it will impact a lot of the implementation but based on the
big modification in many NIP, in particular NIP/01 and NIP/25, I will
need to use mnesia one day or another. What we did during these
shortcuts? Well... Documentation and a first step in the interface to
store clients state. That's a good thing for the first one.
+ created nostr@clients module
+ created interface to create, list and delete clients
~ added documentation
~ did some test to remember how this application was
working...
See you next time friends; I need to drink some water. :')
This commit implements bech32 format and segwit addressing like
defined in Bitcoin implementation. A module called bech32 and another
one called segwit have been created. These two modules offers the
support for encoding and decoding of bech32 string in different formats.
In final, 99% coverage for bech32 and 97% coverage for segwit. The
document is enough for now.
Added an article explaining how and why Bech32/Segwit were implemented
in pure Erlang.
Hey everyone! Ready for a new shortcut session? Well, we should
probably start by reading what we have done last week... So, we have a
working nip/05 implementation, it can be used by the client and the
server. We will need to plug that in our client and/or our routers. If
you take a look on the specification, when an event is coming to the
client with the field `nip05` it should check its content and validate
it. The relay is not correctly supported if I remember correctly, so,
we will probably need to work on that as well. We will also need to
check the content (if it's an hex key or not). Let's do that?
If I want to check this implementation, I will need to configure a
domain name pointing somewhere and returning the correct information,
something like toriko@test.erlangpunch.com (test domain). What if we
configure the server side first? When we have a valid user on our
side, we can enable a local server forwarding to the correct value. It
should be easy to do.
+ created nostr_relay_nip05_handler module (nip05 support on server
side)
+ started just a quick session to test if everything was working. The
documentation is not accurate, need to update it
+ created an isolated nostr_relay_listener:routes/1 function
! need to create a sub-domain to test the application and do a small
reverse proxy (say test.erlangpunch.com).
== 2023-05-23: Shortcut_23/26
Let's start the second round. We will create a local relay handling
.well-known/nostr.json path (without https for the moment).
~ modified router in nostr_relay_listener
+ created nostr_relay_nip05_handler module
+ created nostr_relay_nip05_handler:lookup/3 to search in the
active user (it's only a test for the moment).
! add a way to print the relay where the user can be found
! improve nostr_relay_nip05_handler:lookup_public_key/1.
! improve documentation and add notes, it could be a bit confusing.
? I think I already talked about that, but the current design is not
really correct and needs to be fixed. The goal is to create many
users and they can be connected to one or more relay. In this case,
the internal relay will find them directly from the database of
active user and create automatically the names/public keys
available.
== 2023-05-23: Shortcut_23/27
So, last shortcut tonight, the third one. I will continue to create
nostr_relay_nip05_handler module and will go to bed! This module is
working, at least, locally, with hardcoded values and without
https... But the idea is there. The current relay was implemented to
be only used in test suite, the database is not even correctly
working.
+ added nip05 CORS support
+ added more documentation and notes
+ created a function to list all users on the server
+ created a functio nto list one user on the server
! those functions are using hardcoded values and should not be
used in production ;)
! need to modify the whole structure, like I said previously,
an user should be isolated and select the relay he wants.
So, it's done for tonight! I know, it was not really... fun but we
will improve that very soon. The current application is already
working a little bit, and nip05 was a requirement to use it into the
wild. A will create a custom domain name containing my testing data
and will try to publish some events next week :)
Have a good day, good night, and as usual, thanks for watching! ;)
Hi everyone! So, another shortcut session... We start with lot of
typos to fix. Last week we did the first nip/05 implementation in a
dedicated process using gen_statem. We had some issues with the
connection to the remote server, I found the problem just after the
session, it was due to the TLS timeout I had configured. It was fixed
and it worked. Today, I also updated Erlang version to the latest one
available (R26), cowboy and gun were also updated as well. Those
session will be dedicated to test and finish nip05
implementation. Let's do it!
+ checked if the process was working, and it is the case
+ added few documentation to explain how it's working
! need to modify the way we store the value
! need to create simple interfaces (and document them)
! cleanup the mess... This module is hard to understand at first glance.
? modify the data-structure used?
== 2023-05-16: Shortcut_23/23
Continue to implement nip/05. Fix bugs and try to simplify the way
it's actually done.
+ created is_valid/1 interface
+ created check_identifier_validity/2 to check if the identifier
and the key are the same on the remote server.
~ cleaned up the documentation and the exported functions
! it's still mess...
? is it really the good way to do? exporting a simple function
to check if the identifier is valid could be easier. Another
way is to create a kind of callback to set the value found
and update another data-structure somewhere else.
? this feature will be used by the client and the relay, create
a behavior instead of a full gen_statem could also be helpful.
== 2023-05-16: Shortcut_23/24
Okay, we have some functional, it's working but there are still some
bugs to fix. Let's go for a third round.
+ add notification support (created init_notify/2)
+ add more documentation
+ add identifier/1 and public_key/1 (could be helpful)
~ modified the record, it has now the raw identifier (if valid)
! Add tests...!
! Add a local server to mock this part of the code in the
test suite.
? I think this code will be refactored, some parts are quite
dirty and I don't really like the way it's done. We'll see in
another session.
So, I think we have a working process/module. It's not perfect at all
but we will improve that when the whole stack will work. At least, we
can now check if an identifier is valid (or not). The next step is to
integrate this module/process directly on the client and server
sides... See you soon! :)
Hi everyone! The week was a bit exausting on my side... So, I will try
to continue the previous implementation of nip/05. First, we will read
the change during the last session. Okay! Let's go!
+ created check_json/1 function to check json object returned by the
server hosting the information about one user
+ added eunit test support
+ added more documentation
+ added some todos.
! require documentation on many functions
! need to check the data stored in names and relays attributes.
== 2023-05-09: Shorcut_23/20
Did some cleanup, in particular in the init function.
+ splitted the init function in small functions to check
arguments present in a proplists
+ added module documentation
+ added more documentation
! need to rename this module to nostr_client_nip05
== 2023-05-09: Shorcut_23/21
This last part was dedicated to test the process... And it does not
work correctly. Anyway, it will be fixed next time. When creating a
connection to the remote server with a valid domain and path, nothing
is returned. It's possibly related to CA validation (to check).
Anyway, see you Friday... :)
+ add logging support
+ did some tests
~ fixed a bug in the path used to fetch the information
~ fixed few other bugs
We will probably work on another part of the code. We will finish
NIP/02 and merge it. At this time, the relay is doing to much things
and it was not planned at all. Let's work on NIP/02 and the client
tonight!
The problem we had was related related to the way we should receive
the answers from the relay... We will try to deal with that or switch
to another issue.
We already have a great implementation on the client, but we lack it
on the server side. I think it will be done another day. We will switch
to another issue.
----
Let's add the support for the key store. The idea is to store it somewhere
on the disk. To do that we can use many different methods. Which one is the
best? Well... At first, we will just export the key on a file present in the
filesystem. We will improve it later.
Okay, a nostr_client_key module has been created, it is currently not started
but the idea is to have one process per key. This process will be in charge
to save/update/export the private information stored for one user identified
by a name. At first, the private keys (and other informations) will not
be encrypted. It seems a bit crazy, but we need to start with something simple.
This information should be stored outside of the database because it should
be easy to extract and easy to export.
--[ SHORTCUT_23/05 ]
What kind of messages we need to support there? Well. We need to:
1. (cast) generate a new key
2. (cast) store the key on the disk
3. (cast) load the key from the disk (if present)
4. (call) export it in different formats
The main function created there was the initialization part of
nostr_client_key.
--[ SHORTCUT_23/05 ]
finalizing the initialization part of the nostr_client_key module
using gen_server. This shortcut implemented a way to generate,
initialize, and store a key. More tests are required though.
So, it's over for tonight! 3 shortcuts, one module implemented. It
looks good :)
See you for the next ones ;)
Found a bug in the encoder. Will fix it right now. Better!
Okay, we corrected a bug in the encoder and started to define a new table called
subscriptions. This table will contain a list of subscription identifier (generated
by the clients), the client connected and a reference to a filter (probably another
table). The identifier should be a tuble {ClientIdentifier, Connection}.
mnesia backend. The idea is to create a behavior with the commands to insert,
delete, update and select information from the database. Not ACID... CRUD! :')
Anyway, the goal is to offer some facilities to create those handlers and
extend easily the relay. Inserting an event or a subscription should be
easy on mnesia but also on any kind of database like postgresql.
I think this module will be updated soon with more specification. At least,
it works to insert data in the database (events). The subscription will also
be inserted into the database but the procedure will be a bit different...
and was always happy when developing using that. why shortcut? I wanted "short circuit"
but it was a bit too long... Shortcut looks better!
A quick summary: we coded the supervisor for the nostr_relay subscription, deployed it
started it and created a simple interface to forward the events. More is needed... But
we will see that in another shortcut episode! :)