How to Render Many Webpages from a Single Canister in a multi-canister app?

Hello Fellow IC Developers,

We are nearing the last phase of our SatoshiNotes project, and now we have the challenge of actually rendering the notes online, using the IC.

Myself and our team would be very grateful for any advice you have on how to accomplish this, let me explain first where we are:

  1. We have an Electron Client that allows people to write notes for free, they are in HTML format, and the files reside locally on the user’s own computer. The IC features I will mention later are completely optional, the local desktop app itself works fully and will be free.

  2. We have a canister for registering users. This canister gets the user details, and is in charge of charging the users that want to use the IC features of our app. With the ICP it receives it is able to create storage canisters for the users.

  3. We have user canisters for file storage. Inside these canisters is a BTreeMap structure that contains the user files stored as nodes of an IC Rust Stable Structure.

NOW HERE IS OUR CHALLENGE:

We need to be able to render user web pages from the user canisters, but not one file per canister, but multiple files per canister. There is the additional difficulty that sometimes those files are not free, so we only render part of the file as HTML and ask the person to pay or donate a fee in ICP or ckBTC.

There are many possible solutions to doing the paragraph above, but we are not sure exactly what to do. Can you please suggest some solutions? We are working exclusively with Rust, but we could create a “rendering” canister in Motoko or Rust just to show the user data, or we could somehow add that render function inside the user’s own canister using Rust. I do prefer the last Rust only alternative, but I am not sure if it is feasible now.

If anyone has done this, or can suggest a way forward please let me know. We are building this now, and your advice will be very important to help us finish this project, and show it to you all.

THANKS!

TLDR: you want to use ‘asset certification’

IIUC you want to host static files from a canister similar to our docs. To do so, you basically have two options right now: use the default asset canister and upload your files there, or implement asset certification in your canisters yourself.

If you want to use the default asset canister, you can either deploy one using the canister type asset in dfx, or you can find the wasm here. The interface is described here.

Rolling asset certification on your own is not easy, but sounds like it could be worth the effort in your case. In simple terms you have to pre-certify all valid responses so that you can then serve those via query calls. The best example we have right now is the asset canister itself, but @NathanosDev is working on simplifying the process right now so that it becomes easier very soon.

I’ll leave you with some resources to study on your own first, but I’m happy to help as needed.

Resources:

2 Likes

@Severin first thanks for that thorough answer.

In our case since the data is inside a BTreeMap it seems we have to roll our own asset certification.

How far along is the work from @NathanosDev to make this a bit easier?

Also is there a place you can point me to see the code for your docs, it seems you are doing this already, or is that using the standard asset canister?

Given our use case it seems we can not use the standard asset canister, since we have the data in our own data structure, the Rust BTreeMap you guys developed to store data.

It’s a heavy work in progress, and hasn’t been security reviewed yet, but work so far lives here (including docs): response-verification/packages/ic-http-certification at main · dfinity/response-verification · GitHub

The first stage is aimed to be ready for use in January, this is aimed at generic HTTP certification and isn’t specific to assets.

Later in Q1 I plan to release a follow-up library specific to assets that will be higher-level and will simplify things further.

I would recommend waiting at least for the January release and with this you should be able to wire together an asset certification relatively easily. I’ll have examples of how to do that too, but it will require some understanding of how HTTP certification works.

The follow up library will require very little knowledge of how HTTP certification works because it will essentially configure everything for you.

P.S. the docs are using the standard asset canister. If you wish to see the code for a canister that’s using a custom implementation then Internet Identity is a good example: internet-identity/src/asset_util/src/lib.rs at main · dfinity/internet-identity · GitHub

1 Like

@NathanosDev thanks for your update, and for the link to the docs code.

We need this particular code piece to finish SatoshiNotes, you can see an idea of what we are building on our website preview:

We would really like to finish this in January, I do hope you have the code ready in the beginning of the month, one can hope! :smiley:

1 Like

I could probably finish the implementation early in January, but between documentation, examples and security review, I predict it will be later in January when it’s officially “ready to go”.

If you have a tighter deadline, maybe an early integration wouldn’t be such a bad thing. That way you can work on the integration while the security review is on-going, but I think it would be safest to wait until the security review of the library is finished before releasing your app with the library integrated.

@Severin @NathanosDev Thanks to you both for your answers, they are definitely helpful, but implementing the asset canister on our own, or doing asset certification does look like a demanding effort.

I have a question that comes from a conversation I had with one of our developers. He mentioned building a REST like HTTP interface for our storage canister, so that the canister can respond to HTTP GET requests with the payload of HTML directly, without asset certification.

There is some work on this Github repository, the library is called Pluto:

It is an early version, but you can see what the developer there wants to do would also help us. It is not fully ready now, and the current version of Pluto would not work for our specific use case yet, however it is an interesting approach since it would enable REST access to Canisters.

What do you think about this idea?

I am copying David Dal Busco since he did something related to this work in Juno, and I think he does asset certification himself as well. David @peterparker what do you think of the REST support inside a canister with a library similar to Pluto above?

2 Likes

This is a very cool project that I’m also keeping an eye on. But there might be some confusion about what it offers.

Whether you do a custom asset certification, or you use the library that will be released in January, or you use Pluto, in all cases you are implementing an HTTP interface for your canister. With a simple asset certification, you are only implementing a GET request. You can extend this to include other HTTP methods. Pluto can help you do that in a structured way, which is nice, but it won’t fundamentally change the interface of your canister.

2 Likes