-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
DApp Launcher, Seed High Level API (HLAPI) & Seed Module #4
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
…a on entanglement
…glement and works
…el API) export for module convenience
… functional through API
…hrough moduleLoader.js
…cription hookup for UI to load when balance changes
Merged
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Overview
The following development changes were based upon the design article DApp Launcher. This pull request includes functional, unstyled UI's for the launcher, the Seed module and the Relay module. It also includes dynamically loading modules, a High Level API (HLAPI) implementation for Seed DApps, and functional implementations of the Seed & Relay modules with their UI's.
To reiterate, this pull request was not focused around creating styled UI's, but instead about creating simple UI's which are functional and genuinely communicate with the Seed ecosystem.
Terminology Note: A "Module" is similar to a "Smart Contract" in Ethereum, while a "DApp" is an application which uses Modules.
DApp Launcher
The DApp launcher is created using NodeJS and Electron. It dynamically loads modules, pairs them with the virtual machine, can launch the dynamically loaded UI's for their modules, and offers a high level API for these DApps.
Due to the nature of Electron, all communication between the Launcher window, DApps and Seed (through the API) must be done though interprocess communication (IPC) between the individual pages and the Main process.
Dynamic Module Loading
Modules & their accompanying DApp are loaded dynamically by the Main process. The Launcher UI is then informed and updated to respect these loaded DApps. The Main process does not know anything about the underlying modules, only where to find the downloaded modules and how to load them.
DApp Requirements
There are four primary requirements a DApp must describe to the launcher in order for the launcher to effectively load the DApp.
DApps must:
Be able to describe to the launcher how they wish to be displayed in the launcher
Describe where to find their Modules source code
Describe where to find their UI's source code
State their Modules expected checksum for validation purposes
When being loaded dynamically, the Module Loader will read a module.json file which will explain these for the launcher.
For the purpose of example, the current module.json file for the Seed DApp contains the following JSON object.
{ "name" : "Seed", "dappSource" : "index.html", "moduleSource" : "seed.js", "moduleChecksum" : "fd37" }
Implementation
All modules are stored in the /modules folder in the base directory of the client. Each sub folder of the /modules folder represents a separate DApp that the launcher can launch. Inside each sub folder is a module.json file, which contains a JSON object that describes the above DApp requirements to the launcher.
When the launcher opens, it will read each subfolder's module.json file and dynamically create each tile & associated module. In order to add modules to the launcher, one must simply be downloaded and places in the /modules folder.
The above logic is express in code in the moduleLoader.js file, under the exported function "loadModules".
High Level API (HLAPI)
DApps which choose to be hosted inside the launcher will have the luxury of accessing a High Level API for Seed. This High Level API is referred to as the SeedHLAPI. This API wraps all logic needed regarding how Seed works under the hood, and lets users create transactions, read from modules or subscribe for updates in a couple simple function calls.
This approach differs from the current Seed API, which is now being referred to as the Seed Low level API (SeedLLAPI). The Low Level API (LLAPI) exposes the underlying exports needed to communicate directly with Seed's subsystems, while the High Level API (HLAPI) wraps the logic, removing a developers need from understanding how to appropriately communicate with the Seed subsystems.
Electron Constraints
Electron brings its own set of constraints we must adhere to when building the HLAPI. The primary constraints we must respect is how Electron and the underlying Chromium system its built on communicate across processes.
Each process has its own set of memory, with each window being a separate process. The base process is known as "Main", which creates each individual window. Each window has its own process, which is known as a Renderer. Renderer's and Main communicate with one-other through Electron's IPC channels. These IPC channels cannot have JavaScript references sent through it, so all data or objects that are sent over IPC must be serializable.
Since we cannot send references, the processes cannot communicate with the same Seed API instances directly. Instead, Main must be the process that holds the Seed LLAPI instance used by the Seed HLAPI, and the Renderers must request Main do the processing. These requests must be made through IPC.
DApp Requirements
DApps must be able to make HLAPI requests, wait for a response from a separate process, and continue their work once the execution of the HLAPI has completed. Therefore, the DApps require that the HLAPI is asynchronous, despite the LLAPI being synchronous.
With regards to what DApps must be able to do, DApps must be able to:
Implementation
The implementation of the HLAPI is split into two fronts. The first is how the Main Process implements the API in order to communicate with the Seed LLAPI. The second portion is how the DApp's Renderers make the asynchronous API requests to the Main Process.
This implementation added the requirement of asynchronous IPC communication. In order to meet this requirement, the npm module "PromiseIPC" was added to the Electron clients dependencies.
Main Process
For the implementation of the Main process portion, the code can be found at the bottom of main.js.
The Main process instantiates a PromiseIPC instance to listen for requests by the Renderers. Each API call a Renderer can make has its own listener inside main.js. These calls arrive asynchronously, where the file then works on the request, wrapping any logic needed to perform these actions. These listeners communicate with the Seed LLAPI directly through the index.js file in the seedSrc external folder.
Most API implementations are simple, simply accessing the LLAPI's appropriate export and speaking directly with whichever subsystem is needed. Some calls require a little more work, such as switching accounts.
Renderer Process
For the implementation of the Renderer processes portion, the code can be found in the seedHLAPI.js folder, which DApps can require.
In seedHLAPI.js exists a class known as SeedHLAPI. This class takes a instantiated Renderer's PromiseIPC object upon creation to communicate with Main on the Renderer's behalf. This class is very simple, as the logic heavy side is done by the Main process. The SeedHLAPI class simply wraps the communication logic, making it easier for DApps to communicate without needing to know what channels the Main process is listening for.
Seed Module
The Seed DApp is the first module & DApp available in the launcher. This DApp hosts the Seed cryptocurrency and acts as a wallet for users.
Wireframe Design
The theme will be a simple white background with a light green tint. Upon opening, a users public address will be visible in plain text, as well as a QR code display of that address. The users' balance will also be available, live updating while sending or receiving funds.
The various actions a user can do, such as transfer currency, are listed as buttons below the information heavy header.
At the bottom of the DApp will be the recent transaction history.
Current State
This pull request did not focus on styling or design yet, instead it focused on making every Seed module function implemented in a functional manner.
In the Seed DApp, the users public key and account balance are displayed on the screen. These values update dynamically, so if a user is given Seed or if accounts change, these values will automatically update to match.
There is a drop-down menu which correlates to the different functions in the Seed module. Seed was designed after the Ethereum ERC20 standard for tokens, and therefore there are four primary functions that users can invoke. "Transfer", "TransferFrom", "Approve" and "Burn". On top of that, there is also a "Constructor" option, which can be invoked upon the creation of the module to give it the initial starting values.
When a user changes between these five options in the drop-down menu, the input form live updates to match. These inputs are the same inputs that the functions expect as parameters into Seed. Users can invoke the function after filling in inputs, which creates a transaction and adds it to the entanglement.
Video of forms changing based on selected function
Relay Module
The Relay module is created for development only. This module and DApp allows the simply creation of empty transactions which simply validates some transactions in the entanglement. The Relay DApp will randomize one of one hundred possible users, simulating multiple users pushing the system forward.
The UI is simply a single button which says "Relay".
Honourable Mentions
Unit Test Migration
Previously, the unit tests setup the entanglement and constructed the launch of Seed. Now, that must be done through the UI.
In order to run the unit tests, you must:
Switch to using "Account Cryptography - Public Key Encryption, hashing, base58 encoding & unit tests #1" through the menu system
Open the Seed DApp in the launcher
"Construct" the Seed module, keeping the initial amount in circulation at "1000" SEED
Click the "Unit Tests" button on the main UI.
In the terminal, the unit tests will be run in the main process, showing up in your NodeJS terminal (NOT in the Launcher or Seed windows debug logs)
Video of Seed module unit test being run