So folks! Our beloved cyber funky fellas! Since, decentralization is all around and since everyone is talking about Web 6.9 (..) The time has come for all of us, developers , the lovers of bits and bytes (..) the 0s and 1s (..) to at least consider the possibility of deploying ⋮⋮⋮ UI dApps of our own.
What would you say? Have you not implemented a decentralized application before? Oh! Now, why is so? Have you not considered Ethereum, maybe? Worry not. Truth be told, neither did we… as there ever was so little point in doing so. This time, it is way different, though.
We are talking about allowing for arbitrary user-friendly applications users are already well familiar with when using ‘normal’ operating systems.
Now made decentralized. That is right.
If you are not familiar so much with the benefits of decentralization these let us just name a few, in the context of ⋮⋮⋮GRIDNET OS:
- use technologies you are already well familiar with such as JavaScript, HTML, CSS👾
- these are new grounds so high chances for your application to become popular.
- no need for any server. The network hosts your app all by itself.
- no need to configure any kind of software.
- you can modify your web-page / application from any device. Yet again, – without installing any kind of software.
- nobody can bring your app down.
- nobody, including government institutions ever gets access to any kind of data, including meta-data your app processes.
- anonymous data exchange.
- your app is available from anywhere.
- you are 100% anonymous and so are your users.
- access to data-storage and crypto exchange APIs at your fingers.
- your app looks like it would be running on Windows and/or MacOS X even though it gets launched from a web-browser.
- lots of ways to monetize your application. Ultra fast crypto payments available through JavaScript APIs. You may want to take a look (you do want to take a look!) at our GridCraft game and see how players are rewarded with crypto for finding Gold Veins in a dynamically generated environment.
- the possibility to implement arbitrary logic running on nodes maintaining the network.
- the list goes on and on. Limited only by your imagination.
If, you are not a developer, worry not as developers are to come to like ⋮⋮⋮GRIDNET OS so much, soon enough you are to be seeing an eruption of decentralized User-Interface equipped applications making their way onto the platform. Talk about a Tsunami of ideas now made possible to become Real at the least amount of effort required. With all the building-blocks Easily accessible from a single, coherent decentralized development and runtime environment.
Wizards are Real. (..) You remember that (..)
Now, this article is intended for developers. What kind of developers? All developers are welcome! Still, if you’ve got some solid background in JavaScript, CSS, HTML and neighbouring technologies you would feel just at home.
Our time is precious, so let us get straight down to business! Shall we?
⋮⋮⋮ Rationale
So we all have heard about decentralization. Decentralized state-machines. Bitcoin, Ethereum and stuff. Guess what? People now want their applications decentralized! Games, collaborative apps, content delivery networks, services such as YouTube, Twitter, exchanges; anything and everything! And there are some good reasons behind these market preferences! For more unbiased background on the evolution of decentralized systems – from Bitcoin, across Ethereum towards ⋮⋮⋮GRIDNET OS check out this article and draw your own conclusions. At any time, feel invited to visit https://talk.gridnet.org for a discussion.
Is that MacOS X2? Windows 2022, maybe ?
Everything a developer might ever need to make her ideas a Reality. The system makes sure she never needs to mix centralized and decentralized architectures. At least no more.
Storage of large files? Sure! Incentivisation of nodes for having parts of these files delivered to web-browsers? Sure! Cross-browser communication? Wait a sec! How about Onion-Routed cross browser communication while the exchange of data packets is incentivized through cryptocurrency? Easy. Windows? Window Managers? Package Managers? Access Control List-based file system? It is all there, just waiting to be used. Ease of development? Inherit from CWindows class, change the default Package ID, window title and voilà, you’ve just created your very first Hello-World decentralized windowed app. No other platform provides. That is how it is.
All the fancy APIs, accessible from JavaScript wrap around the underlying uncertainties or performance troubles stemming from decentralization. Same for communication. No need to be familiar with browser specific WebRTC implementations. Just instantiate a ⋮⋮⋮GRIDNET OS Swarm and sign up for events!
⋮⋮⋮GRIDNET OS would be making sure everything is end-to-end encrypted at all times and decentralized. Yeah, our wrappers around WebRTC are probably the first implementation which entirely eliminated reliance on centralized servers as it holds true even for initial signaling, making sure the initial WebRTC handshake between browsers is carried out through random nodes comprising the network.
Want your application to be notified about things happening in its environment? Like what happens to its window, whenever the window gets resized, minimized, maximized, whenever the user hovers over the window? Whenever data arrives to your application from the decentralized network of nodes? Whenever a user logs on? Whenever another application receives a certain kind of data? Whenever another application attempts to commit data onto the decentralized state-machine? Whenever state of user-owned files gets changed, maybe?
No problem! Simply sign up for appropriate events.
Worried about concurrency issues while having your User Interface-equipped decentralized application requesting data from the decentralized state-machine or committing data? Worry not, ⋮⋮⋮GRIDNET OS ? It would be taking care of all of that. ⋮⋮⋮GRIDNET OS – it provides, remember? So that you may focus on the idea of yours.
It was implemented by passionate folks on YouTube LIVE since the early 2017, where there are now well over 35TB of Live programming sessions available. Should you have any kind of ideas and or requests head straight over to https://talk.gridnet.org. Each decentralized project you work on you are alone no more. Now, it is you and ⋮⋮⋮ GRIDNET OS. You have one aim and one aim only – to make your decentralized dreams a reality. Everything else is on the shoulders of the former.
⋮⋮⋮ Architecture
When it comes to creating applications and their corresponding architectures,- an ⋮⋮⋮ Application is composed of code running at nodes maintaining the network and code running within web-browser(s). The former is written in #GridScript, while the latter employs JavaScript – for the most of it. Indeed, ⋮⋮⋮GRIDNET OS makes everything available through easily accessible ⋮⋮⋮ JavaScript (ECMA 6) APIs. The two realms can be mixed or decoupled, depending on your requirements.
What are the benefits? One may choose to deploy an application composed solely of #GridScript, effectively resulting in something reassembling what Ethereum allows for (what they call a ‘Smart-Contract‘… we all know Ethereum was doomed to remain with its one leg stuck in the realm of finance, like forever. Whatever). Then, one may choose to use solely front-end technologies such as JavaScript and interact with the environment (data storage, communication, UI, events etc.) through the ⋮⋮⋮GRIDNET OS’ JavaScript APIs. And finally, one may choose to mix both realms! An example? Our GridCraft game, it takes heavy use of front-end technologies for dynamic game-world generation through web-workers and it employs code running at full-nodes for dynamic spawning of Gold-Veins appearing underground, depending on the current player’s position. The code, running at full-nodes analysis players’ positions in real-time, employs anti-cheat mechanics and issues crypto-rewards once player successfully finds and digs out a gold vein. Could Ethereum provide? No way😉
Going deeper, from the JavaScript developer’s perspective all the APIs are exposed through the CVMContext singleton. It is the main object all the other components and thus APIs are made available from. One may access these at any time by calling CVMContext.getInstance() static method.
Now, let us get going and deploy our first ⋮⋮⋮Hello World UI dApp, shall we?
(..) you are about to deploy your very first Decentralized Hello World UI dApp! on the very first 100% decentralized operating systems! You might thus very much feel like developing first windowed app for Windows 3.11 back in the early 90s! (..)
While the ⋮⋮⋮GRIDNET OS UI dApp does not do much besides displaying its window and querying user for some data, it effectively demonstrates interactions between an average application and the operating system. Interacting with some of the main APIs, signing up for events etc. For more advanced mechanics feel invited to look through sources codes of other UI dApps that are available within the repository. These cover data storage, video streaming, gaming etc.
⋮⋮⋮ Hello World UI dApp
Get The ⋮⋮⋮ Template From 😺GitHub
First, let us visit the ⋮⋮⋮GRIDNET OS’ GitHub repository available right over here. While you may want to check-out all of the UI dApps, for now we are to pay special interest to one file in particular, the UserDeployable.app – which is a self-contained ⋮⋮⋮UI dApp Package.
Since an ⋮⋮⋮UI dApp Package, in its simplest form, is a JavaScript file with its extension set to ‘.app’ – you may want to change the extension to ‘.js’ for editing purposes, so to have all the in-code-highlighting within the favourite code-editor of yours enabled (Atom is great! Almost all of the ⋮⋮⋮GRIDNET OS‘ JavaScript components were written within of it.)
⋮⋮⋮ GRIDNET OS makes it possible to edit and implement applications right within of the system through the ⋮⋮⋮ Editor UI dApp. While its possibilities may be a far cry (at least for now) when compared to code Editors you my be familiar with, still it might be great to know that it is possible at all! To introduce hot-fixes to any files, from any computer also an untrusted one! Without needing to install anything.
What comprises a minimal ⋮⋮⋮Code Package? An ‘.app’ file having a single class inheriting from CWindow defined, together with all the ⋮⋮⋮Package interface functions implemented. The operating system expects the implementation of the former to be set as a default export. These would be looked for by the ⋮⋮⋮Package Manager once the user attempts interact with the package file, presumably so to have it installed.
UserDeployable.app, while being a sample, readily installable code package, it may be treated as an UI dApp template. We shall proceed with changing just a couple of lines just to get an overlook of how things are structured. Let us now go through the template file together, shall we?😌
⋮⋮⋮ Template Checklist
Once opened, the file welcomes us with a rather short to-do-list. These points are to ensure a customized experience once your UI dApp , based on this template, gets installed and then launched. It takes you by hand through things like defining your app’s Package ID, icon, title , contents of the main Window and so on. It all takes two or three minutes if you have got all the values already in your head.
⋮⋮⋮ Imports Section
Scrolling further, right after the checklist we see a code section related to ‘imports’. ⋮⋮⋮GRIDNET OS provides a variety of objects and APIs. First though, one needs to import the components that are about to be used. Just remember to use relative paths, starting from the root of the ⋮⋮⋮File-System. Make sure that the file paths begin with “/“ . That is important, since the ⋮⋮⋮Package Manager, under the hood, it does some crazy cool stuff allowing for ECMA6 classes to be loaded from byte arrays, even before the files are committed onto the decentralized network. This in turn gives us the possibility to test how everything works in sandbox-mode, before proceeding to deployment. Let us Flow!
Let us now go real quick over things that are being imported:
- ⋮⋮⋮ CWindow – a class representing.. you’ve got it right! A Window! There are other classes covering ⋮⋮⋮Threads and ⋮⋮⋮Processes as well, while CWindow wraps these under the hood so you do not need to worry about any of the details while creating an simplistic app. Through CWindow one may get and set a variety of properties and interact with your UI. Force the window to get resized, check its current size, disable min/max icons apparent on the window’s title-bar and so on. CWindow would take care of the default events’ processing queue and spawn a single thread for you the very moment it is initialized. It would also make sure, by default, that the app appears at the ⋮⋮⋮Taskbar and that the previews of its contents are made available as its icon on the ⋮⋮⋮Taskbar hovered etc. Everything taken care of by the system.
- ⋮⋮⋮CTools – now you are to come to like this class. Data encoding, compression, type conversions, animations, instantiation of images from byte arrays etc. It is all right over there. A real Swiss Army Knife, waiting to be used, proper handling of exceptions assured.
- CDataConcatenator – now that is a very low level utility. Basically, it allows for any object to be serialized into a decentralized-state-machine-compatible byte vector.
- ⋮⋮⋮CSettingsManager – your app might want to offer persistent settings. This ⋮⋮⋮API would ensure that these settings are loaded with each and every launch of your application across user sessions. Everything events-driven. Just keep updating the ‘settings object’ within your app with new data and the system would be taking care of the rest. Ensuring the data is always up to date. easy peasy!
- ⋮⋮⋮CContentHandler – Are you creating an image editor? Your app might want to register, with the operating system, file-type handlers for say ‘.png’ and ‘.jpg’ file extensions. Then, once the user attempts to open either file-type, she would get to choose among the registered UI dApps.
- ⋮⋮⋮CNetMsg – ⋮⋮⋮GRIDNET OS UI dApps support crypto-incentivized data exchange. Data might be taking a variety of paths. From one web-browser to another, data may be onion routed across peers, be flowing through multiple full-nodes comprising the GRIDNET network or be on its way straight to the user’s mobile app. End-to-End encrypted at all times. At least by default. Because in the end, you are the developer. You get to choose. Anyhow, CNetMsg is an envelope containing the payload.
- ⋮⋮⋮MetaData – ⋮⋮⋮GRIDNET OS boards its own data-exchange meta-language, which is based on BER (Basic Encoding Rules) binary encoding. Thanks to it, we get a very efficient meta-language which is binary encoded. This stays in contrast with say XML or JSON; The language, it is well understood across all of the platforms involved: Web-browsers, full-nodes and mobile apps. It is also very storage efficient. There will be a separate article tackling this very topic.
⋮⋮⋮ Window Contents
As we scroll down, we get to define contents of a ⋮⋮⋮Window. The template supports loading data from another file or through the inline ‘appTemplateBody’ variable.
For defining window contents feel free to use use technologies that you already well acquainted with meaning HTML and CSS; worry not about data-presentation boundaries or whether your CSS would affect another UI dApps, or the systems itself, as the latter assures proper compartmentation through the Shadow DOM technology now available in Chromium. You may choose to use additional files and import these for code-clarity. For the purposes of this tutorial, we would not be adding any additional UI components and leave the default style sheets as they are.
⋮⋮⋮ UI dApp’s Constructor
As has been already covered, your decentralized, graphical application inherits from CWindow. The constructor o the derived class. it is its main initialization point. Anything that needs to be set before the main window of your app is shown? Put it right over here. Otherwise, plug your logic into an appropriate event handler, fired once the window gets opened.
Now, let us change the derived class’ name ‘CUIAppTemplate’ to something else. Simply replace all occurrences of ‘CUIAppTemplate’ with something more personal. Here, we will simply go with ‘CMyHelloWorld’.
Notice how the app registers Callback Functions with some ⋮⋮⋮GRIDNET OS APIs. First, it registers a Callback Function with the already mentioned ⋮⋮⋮MetaData sub-protocol. The sub-protocol is used for signaling. Thanks to it, we are able to react whenever anything of significance happens in the local environment, but also at another web-browser, at a full-node or at the user’s mobile app.
Going further, our app registers yet another Callback Function with the ⋮⋮⋮Decentralized File System API. Also, another callback function goes to the ⋮⋮⋮GridScript processing API – so that our application is notified and thus, yet again, able react to results of ⋮⋮⋮GridScript code processing happening at full-nodes. Within the event handler, the app would then be able to check whether the event originated as a result of ⋮⋮⋮GridScript code-processing issued on on behalf of our application, or maybe the code processing was requested by another ⋮⋮⋮UI dApp running within the system. This indeed gives as the ability of plugging right into logic of external applications.
Hold your horses! We are to be taking a closer look at implementations of sample callback functions later on.
Let us go back to personalizing our application further. Here in Atom, we simply hit CTRL+H and replaced ‘CUIAppTemplate’ with ‘CMyHelloWorld’. There were 17 occurrences. That was rather quick, was it not?
As the former checklist commands, we shall now change the title of the application, which is shown within the title bar, once the UI dApp gets launched,- just as one would expect. Right? Let us proceed in accordance to its rulings.
We just changed the title to “My Hello World App”. Yet again – easy.
Note: you would be able to change title of your window during runtime, dynamically through the Window API.
⋮⋮⋮ File Handlers
As we scroll further, we cross over a code section in which File Handlers are being defined. The uncommented part of the section,- it establishes two file handlers. One goes for files containing arbitrary binary data (eDataType.bytes) and the other for unsigned integers (eDataType.unsignedInteger). These are called implicit file-type handlers, since they do not specify explicit file-type extensions.
Indeed, under the hood, each file on the ⋮⋮⋮Decentralized File System is of a certain type, even if it does not come with an ‘extension’ after a dot in its name. Same as on MacOS X. One could also find similarities with the Microsoft Windows’ alternative data streams. By default, any user-created file has a data type equal to eDataType.bytes, meaning an arbitrary byte vector. The system does its best to toggle between the underlying file-type as needed. At the bottom of everything these represent types of nodes in a Merkle Patricia Trie. If the system detects a byte array to comprise a valid Big Integer it would change the file type to a more relevant etc.
Here, going back to our file, the commented-out section depicts how explicit file handlers could be defined, in this example, for *.jpg, *.png and *.webp file types respectively.
Let us keep scrolling through the template file.
⋮⋮⋮ Package Identification
Scrolling even further, we arrive at functions called by the operating system when it needs to query our app about some of the package- identifying properties.
The ⋮⋮⋮Package Identifier. You may consider it as a name-space of your application. Basically, it needs to contain the ‘ org.gridnetproject.UIdApps.’ prefix and it needs to be unique. Only alpha-numerical characters. Easy.
For all the presentation purposes, such as coming up with a string to be put into a shortcut leading to your app, the system would derive your application’s nicely printed name autonomously, from the suffix of the ⋮⋮⋮Package Identifier. So, in our case, when presented to the user, the shortcut would read “My Hello World” – placed right onto the ⋮⋮⋮Desktop once installed.
Hint: use alternating capital and low letters in the ⋮⋮⋮Package Identifier, as that is where a whitespace would be placed.
Now, what about the the Default Category? It tells where your UI dApp is to land in system-related places such as the ⋮⋮⋮Start Menu.
Icon – an icon which appears at the upper left corner of the window also on the Desktop etc. One may provide an icon as a base64 encoded string. The system would take care of all the scaling, aspect-ratio maintenance matters, etc.
⋮⋮⋮ Settings API
Then, we proceed to a section related to the ⋮⋮⋮Settings API. The ⋮⋮⋮System detects autonomously whether your package implements the appropriate public ⋮⋮⋮Settings API relevant interfaces. Once detected it would sign-up for all the relevant processing all by itself. If you desire support of persistent settings make sure to implement getSettings() public prototype function in particular. ⋮⋮⋮GRIDNET OS was designed with end-user and developer in mind, remember? We want you to become hooked onto our technology same as Microsoft and Apple strive to addict their developers, but in the return.. we provide ..always for free. And we provide Big Time.. so that you can materialize the ideas of yours.. the decentralized ideas of your using least effort and cost. Wizards🧙🧙♀️put a lot on themselves indeed, so that you focus on your particular idea. Microsoft and Apple were conceived in times when there was no cryptocurrency around (..) no decentralized state-machines (..) here, the more apps, the more developers are satisfied, the higher popularity of the underlying crypto asset (..) meaning higher its value (..) meaning higher returns for everyone. And so everyone is happy!
So, in order to support dynamic, persistent settings your application would be returning a new updated version of CAppSettings, once queried by the System. At the bottom of everything CAppSettings is a wrapper around your custom arbitrary JavaScript object (note ‘obj’ provided to its constructor below).
The app may keep invoking setSettings() whenever relevant settings change. The system would autonomously query your app, from time to time, for these. In the end these might be any kind of values your application needs to ‘remember’. You may also enforce storage of your settings by invoking saveSettings(). The system would invoke activateSetings() whenever new settings became available, it is then your responsibility to retrieve current settings through CMyHelloWorld.getSettings() and apply relevant changes to View / Model as needed.
Examples? The Walle(t) UI uses settings to retrieve Wallet’s transaction history. The Browser UI dApp uses Settings to allow users to customize the looks and feels of external websites.
⋮⋮⋮ Custom Initializations and Local Threads
Now,The initialize function. Every CWindow comes with a thread of its own. Here, a separate user-mode UI Thread is spawned through the setInterval() function. The function also explicitly loads the current settings and reports on result through the logEvent() method of CTools. These log events appear in an appropriate section of the animated, retractable Logging Pane, also within the Google Developer Tools console window.
Here, we may enter any instructions to be executed at a interval specified earlier. One may want to put these instructions into the ‘Operational Logic’ code-block.
⋮⋮⋮ Overriding Window Events
Indeed, ⋮⋮⋮GRIDNET OS promotes object-oriented, events-driven development. What follows are callback functions to events our UI dApp signed up for.
Overriding window-related functions. Developer are allowed to override user-mode window-related functions at their discretion. Functions related to resizing of Windows, scrolling, etc. Looking at out template, here we have window-related events. Fired whenever the window gets resized, scrolled, etc.
There are a multitude of window-related events you app may plug right into.
⋮⋮⋮ System Callbacks
Further, we have callback functions our app explicitly signed up for,- during its initialization, within the Constructor, as seen earlier.
Remember, as the app signed up for certain kinds of events right within of its Constructor? Now, can you see how the newDFSMsgCallback checks whether the Decentralized File System Message contains results related to a file-system query that was issued by our app? Each invocation of the Decentralized File System API returns a request identifier, which is kept track of by CWindow, for your convenience. Now, all it takes to verify whether the callback is relevant to us is to invoke hasNetworkRequestID of CWindow.
By the end of the template, CMyHelloWorld is exported as a default export. Yet again, that is important as the ⋮⋮⋮Package Manager would be looking for it.
Now, this is all it is to the Template! Feel free to browse the multitude of source codes on GitHub for some advanced usage of a variety of APIs! Server-Less, crypto-incentivized WebRTC swarms? Sure! Live audio/video streaming with screen sharing? Sure! No knowledge of WebRTC needed! The system wraps everything for your convenience! Decentralized Threads running at full-nodes? #GridScript code-processing code in real-time? To be seen, nowhere else? Sure! Many additional tutorials are on the way. The code of the sample apps is very well documented though.
Deployment
Now, how about deploying our Hello World UI dApp onto the decentralized system? Simple!
Change extension of the file to *.app and drag and drop it right onto the ⋮⋮⋮File Manager. Just like seen below:
Deploy the package just like you would any other file by tapping onto the ⋮⋮⋮Magic Button.
You may install the app in SandBox mode just by tapping onto it, even in sandbox mode, before the package is committed onto the network, for testing purposes.
If everything works well, you may choose to Commit your ⋮⋮⋮UI dApp onto the ⋮⋮⋮Network, so to make it persistent and available across the 🌎Globe.
All it takes is to tap onto the ⋮⋮⋮Magic Button.
If you see a ⋮⋮⋮QR Intent straight away, it means you were not logged in. Scan the ⋮⋮⋮QR Intent.
If you were logged in, you would see a work-flow such as the one below:
Installation
From now on, your very first ⋮⋮⋮UI dApp is accessible by anyone! The user just needs to access your State-Domain and the *.app you have just deployed.
Running the ⋮⋮⋮UI dApp
The app just made its way onto the Desktop! Pretty cool, huh? Now, double click on it to have it launched!
Note that our Hello World app registered two implicit file handlers so it would be listed as being able to open files whenever a file is right clicked.
Or the system would use it by default if it is the only app registered with a particular implicit of explicit file-type.
Everything Combined
On The video below you may see all the steps combined together, starting with a Developer logging-in into the system, launching the ⋮⋮⋮File Manager UI dApp, dragging the Hello World Code package from his native operating system onto the decentralized ⋮⋮⋮State-Domain within the ⋮⋮⋮File Manager UI dApp and having it deployed.
Things To Consider
By default, ⋮⋮⋮ UI dApps are deployed on the ⋮⋮⋮Eternal Storage, meaning full-redundancy storage. You may store assets using ⋮⋮⋮Crowd-Funded Storage though. Such as large texture or video files. That would still be 100% decentralized while not relying on centralized paid-for hosting servers. As for the ⋮⋮⋮Eternal Storage, keep in mind that the storage fee depends on the size of your file. Thus, you might want to use JavaScript code minification, etc. This time it indeed does pay to do so!
More tutorials and more documentation on the way!
~~Forever Yours
Wizards🧙🧙♀️