I am IMMUTABLE - Safe Blog App

A week or so ago, I decided to combine some personal training with a small Safe Network app project. I wasn’t sure exactly what I wanted to do, but I wanted to play with the following - Angular, Rust and WASM. I’m not new to Angular, but I wanted to create something useful to put on my github account. Rust and WASM, are new to me though and it was fun to have a play!

So, what is the result? Well, as I do a bit of blogging, I thought a blog app which could read articles from Safe Network would be handy. As we don’t have a working browser for the network, I wanted to explore integration with a clear net browser. I didn’t just want something that only worked on clear net though, so I designed it to work on a future safe browser too - one blog for both platforms.

The client app is written in Angular and it is ready for both a WASM integration and a native safe browser. The app itself doesn’t really care where the data comes from, as long as it can ingest it. WASM in current form couldn’t retrieve articles directly, but I did create a noddy service to just fetch JSON documents from a WASM binary, which satiated my desire to learn a bit about it.

Articles are stored to the Safe Network in Markdown format, then added to a JSON index. The client uses the index to show the articles on the blog home page. The articles are converted into HTML on the fly by an Angular plugin. Any Safe URLs are converted to use the gateway endpoint instead, including images in the articles. All these things can happen in a working safe browser too.

I called the app ‘I am IMMUTABLE’, as I like the double meaning. You can find the code here:

As a clear net app can’t directly access the Safe Network, I decided I needed some sort of web service back end. After mulling a few options, I figured that trying out a Rust web framework would be useful. After an unsuccessful play with Rocket (it doesn’t like tokio!), I went with a bleeding edge version of Actix (which does like recent tokio!). After having some fun with broken sn_client dependencies (thanks for help, @bochaco!), I got something working.

I decided sn_httpd was a decent name, although maybe a touch pretentious! :smiley: It does feel like the basis of some sort of Safe Network HTTP server though. It has two main functions:

  1. Host static files through standard Actix routines.
  2. Provide an endpoint to retrieve blobs of data from the Safe Network.

Hosting static files is nothing novel, but I used the example sn_api code as a basis to integrate the sn_client directly into the sn_httpd app. When you hit /blob/, it goes and fetches the data from the Safe Network, defines appropriate caching and returns it to the client. ShortSafeURL is just the bit after ‘safe://’, e.g. ‘myurl’ for ‘safe://myurl’.

This means you can server an Angular app (static HTML/CSS/Javascript) and let it connect to the Safe Network via GETs to /blob/. Moreover, XOR URLs return headers to cache indefinitely, allowing the browser to just get them once.

You can find the code here:

Then I wanted to provide some configuration/build support, so I had a crack at some Docker containers and scripts to help pull it together. I created a container to bundle a compiled sn_httpd along with the i-am-immutable client. I messed about with trying to get a local network container working too, but Docker/sn_node didn’t like each other enough. In fact, even getting sn_httpd to talk to a local network required a host network (Linux only!). So, all work in progress, but you can find it here:

There are many, many things I would like to add, but I wanted to get to a sort of proof of concept point. I think the above do that quite nicely. It proves we can make hybrid clear net/Safe Network apps, which share data with both platforms. Yes, it is a bit slow, raw, basic, but it works. I’m quite pleased with that!

Some screen shots of the action!

There is some information about how to set it up in the README files. You don’t need to host it on AWS or some such - it can be hosted locally just fine (block that! ha!). Running on a hosted environment is possible, but anyone could leach the bandwidth to any blog on Safe Network (I have plans for that too…), so take caution.

I hope you like it! Have fun!

53 Likes

Really nice work! Love the name. A short acronym for it could be IMIM.

11 Likes

Yes! Most excellent. Good work @Traktion!!

11 Likes

Any chance this becomes a packaged app that anyone can run? Guessing the main issue is choosing the network to bootstrap to like a current Testnet or local network.

Would be cool to see people uploading and sharing blogs over the test nets.

Very neat and I love that it’s network/clearnet agnostic! Good work

9 Likes

@Traktion just dropping in with a quick
clipart1863908

4 Likes

Traktion, its Beautiful!

5 Likes

Thanks! Love that acronym too! Catchy! :smiley:

3 Likes

Yes, there could be various ways of packaging it. Right now, you literally just need the sn_httpd binary and the handful of angular text files (js, css, html, etc). The docker container just bundles these together so you can just run the container and then point your browser at it (like I do in the screenshots - on localhost:8080).

I should be able to push a pre-built version of the container up to docker hub or AWS registry too, which will make life easier. Then you would just need to have docker support on your device to run it.

I think the issues with docker connecting to my local test net are only my issues too (which are only needed for dev, obviously). When we get another test net, I’ll try pointing it to there and see how we get on. I suspect it will be smooth enough! :sunglasses:

There are other options too. The angular static files could be baked into sn_httpd too, to create a single binary with everything in it. These could be built to different targets and run directly. It could figure out where the live safe network is by itself too. So, you would then just run the binary and point a browser at it - pretty simple!

Going one step further again, you can create standalone apps, which are basically web apps under the hood (e.g. electron). These could integrate the sn_httpd binary and the angular code and wrap it all in a single app to load/use on the desktop. I don’t think it is too tricky, it is just a matter of time/effort really!

For mobile, it may get more tricky. I know Maidsafe have experimented with some of that direct rust library integration before. However, even if the mobile has an app which just talks to a gateway server, that would be similar to most apps in terms of user experience.

So, lots of options. It’s just a case of assembling the components in the most useful and accessible way. For some, a hosted web gateway may be super handy. For others, local instance is better, where it can’t be blocked or censored. Once we have a working native safe browser again, we will get some more options there too!

Thanks, appreciated! I’ve toyed with creating a CLI version for giggles too. I know there are some markdown readers out there and it would just be a case of squirting the data to these in a simple way. There is something more immutable about a CLI too for some reason! :smiley:

4 Likes

For those who just want to pull a docker image and run it, I’ve setup Docker Hub too now:

TLDR, on a Linux host you can run:

git clone https://github.com/traktion/i-am-immutable-docker.git
cd i-am-immutable-docker
./sn_start_testnet.sh
docker pull codiate/i-am-immutable:latest
docker run --network host -t codiate/i-am-immutable:latest 127.0.0.1:12305

Then open your browser and go to: http://localhost:8080/blog/yourblog where yourblog is your blog index (see i-am-immutable-client README for how to create one).

For Windows/Mac, I need to understand why a local test net can’t be connected to. Sorry!

7 Likes

Great name for the app! Cant say I understand the details but sounds like you put some real work in there. Maybe consider the BGF once they start looking into funding apps?

10 Likes

I’ve created a sn_httpd release and built binaries for Linux and Windows 64 too.

If you download the binary, then create the static directory (from the same directory as the binary) with associated i-am-immutable-client files, you should be able to run it that way too (including windows!). Static files are here:

On Linux, you then run the command like this:

./sn_httpd.linux.x86_64-unknown-linux-musl 0.0.0.0:8080 static 127.0.0.1:12305

On Windows, it should be something like this:

sn_httpd.exe.windows.x86_64-pc-windows-gnu.exe 0.0.0.0:8080 static 127.0.0.1:12305

I’ve not got a Windows box to try it out on, but Rust seemed to build ok! :smiley:

EDIT: Note that 127.0.0.1:12305 is the safe network address. If you are using run-baby-fleming, take the genesis IP:port and use it here instead.

2 Likes

Thanks - it was a fun learning experience! :slight_smile:

It would be great to get some BGF support and take it to the next level. There are loads of features I would like to add longer term and I’m sure there would be plenty of good ideas from folks here.

I also see this as a platform to create other apps which can work well as hybrid clear/safe net apps. Adding write access in some way would help this too. Some fun for another day though! :slight_smile:

13 Likes

Excellent In the voice of Burns

Love the work you’ve done here and will be a great App for the new network. And you can use it to blog your progress too. :slight_smile:

7 Likes

Great to see you both making at last and having fun doing it Paul. I hope you’ll find time to do more and that the BGF can help when it opens up to apps. Good luck and :clap:

7 Likes

Would posting a link to this on r/programming be well received there?

1 Like

I was planning on writing this up in some blog posts, which talk through the components and design. They maybe better to share with a wider audience, but I don’t mind if anyone wants to link this post anywhere.

The code isn’t my finest work, as its mostly a prototype, but I’m sure folks get that! :laughing:

3 Likes

:partying_face: :partying_face: :partying_face: :partying_face: :partying_face:
I’m not going to lie, it took me a few tries but I figured it out!! great stuff @Traktion

12 Likes

That’s awesome! I really appreciate you taking the time to give it a spin! :sunglasses:

If the instructions need some refinement (they probably do! :sweat_smile:), any notes or even a PR would be welcomed. I know there are a few moving parts to pull together still, but hopefully it wasn’t too bad!

You should stick some images in your test blog there too. It’s quite surprising how quick they load when the browser is instructed to cache them indefinitely.

I want to explore some markdown extensions for music and video links too. From what I’ve read, it should be possible. Being able to stream safe network video and audio to a clear net browser would be pretty cool! :sunglasses:

10 Likes

I consider myself the problem :slightly_smiling_face: not your instructions which are very good.

At work now but will come back to play with this a little later, will let you where I got stuck and what I didn’t/don’t understand then.

Edit: @Traktion

./sn_start_testnet.sh confused me.
I had some issues here but I figured those out. Definitely user error.

The other issue was simply that I did not read the instruction properly.
I was using http://localhost:8080/blog/yourblog
instead of
/blog/<blog-index-safe-url>/article/<article-safe-url>
that was due to this post and me not reading the entire README as suggested.

Those were my only hurdles, so nothing really.

Looking at my MyTestBlog though both Home & Article are active (not the case in your screenshot) where have I gone wrong here? Clicking on either clears the screen until I use the back arrow.

2 Likes

Both of the following should work:

/blog/<blog-index-safe-url>

/blog/<blog-index-safe-url>/article/<article-safe-url>

The former should show the index and the latter should show the article. If that doesn’t work, something isn’t right! :grinning:

The former should have ‘home’ active and the latter should have ‘article’ active. If that doesn’t work for you it could easily be a bug!

1 Like