Skip to content

Commit

Permalink
Merge pull request #81 from obsidiansystems/to-upstream/obsidian-syst…
Browse files Browse the repository at this point in the history
…ems/dex

Latest changes; add wallet worker, UI improvements, update docs and readme
  • Loading branch information
hSloan committed Sep 24, 2021
2 parents 2eedb27 + 5d39067 commit 3ed20ee
Show file tree
Hide file tree
Showing 19 changed files with 1,432 additions and 770 deletions.
10 changes: 5 additions & 5 deletions use-case-2/ARCHITECTURE.md
@@ -1,16 +1,16 @@
##Architecture

This document is in place to give the developer a high level understanding of how this app's structural design. In this document you will find information about request/response handling, smart contract interaction, smart contract and transaction fee estimation, relational database schema layout.
This document is in place to give the developer a high level understanding of how this app's structural design. In this document you will find information about request/response handling, smart contract interaction, smart contract and transaction fee estimation, relational database schema layout.

### Request Handlers

Requests that have the intention of communicating with the smart contracts are made on the frontend and sent to the backend of the application where an HTTP request is sent to Plutus Application Backend(PAB) that simulates communication with a deployed smart contract. A list of API requests can be found within `common/src/Common/Api.hs`. Note: Some familiarity on how to read Haskell function headers will immediately provide you with an idea of the input and output to these application APIs.
Requests that have the intention of communicating with the smart contracts are made on the frontend and sent to the backend of the application where an HTTP request is sent to Plutus Application Backend(PAB) that simulates communication with a deployed smart contract. A list of API requests can be found within `common/src/Common/Api.hs`. Note: Some familiarity on how to read Haskell function headers will immediately provide you with an idea of the input and output to these application APIs.

### Request Responses

Responses to requests that have been made are not returned from the http request made on the backend of the application. Instead, the responses for the request can be discovered in two ways.
Responses to requests that have been made are not returned from the http request made on the backend of the application. Instead, the responses for the request can be discovered in two ways.

One way is to submit an empty request to the `http://localhost:8080/api/new/contract/instances` endpoint and parse it's response for the `observableState` JSON key. Within these `observableState` JSON objects, there will be another key called `tag` provide the subject matter of the state being observed. For example, if awaiting the results of a Swap requests the value of `tag` will be `Swapped`.
One way is to submit an empty request to the `http://localhost:8080/api/new/contract/instances` endpoint and parse its response for the `observableState` JSON key. Within these `observableState` JSON objects, there will be another key called `tag` provide the subject matter of the state being observed. For example, if awaiting the results of a Swap requests the value of `tag` will be `Swapped`.

The second way is to listen for incoming smart contract `observableState` via websocket. Connection with the PAB websocket is established in this case using `ws://localhost:8080/ws/[contract-instance-id]`. In the frontend, Reflex-FRP's websocket libraries are used to detect changes in websocket data to generate events to provoke updates within the DOM. This is how it is possible to know when a swap was successful, when to update the wallet balances, fetch, and perform other calculations based on incoming response data.

Expand All @@ -25,4 +25,4 @@ Transaction fees are derived using regression analytical algorithms on a history
There are 3 tables persisting information in this application.
1. db_contract - The contract id of available wallets that can interact with the Uniswap smart contract. This table is used to display the available wallets a user can perform smart contract actions with on the landing page of the application.
2. db_pooledTokens - The available tokens with supportive pools that enable them to be swappable. This table is used to display tokens that can be swapped in dropdown menus.
3. db_txFeeDataSet - The history of smart contract transactions. This table is used to assemble a data set of uniswap transactions that is later referenced during transaction regression estimation.
3. db_txFeeDataSet - The history of smart contract transactions. This table is used to assemble a data set of uniswap transactions that is later referenced during transaction regression estimation.
60 changes: 36 additions & 24 deletions use-case-2/README.md
@@ -1,10 +1,10 @@
## Welcome to The POKE-DEX (Plutus Obelisk Koin Economy Decentralized Exchange)

This Dapp demonstration allows users to swap and stake tokens using token exchange smart contracts on the Cardano block chain.
This DApp demonstration allows users to swap and stake tokens using token exchange smart contracts on the Cardano block chain.

This Dapp is made possible using the IOHK's Plutus Application Backend(PAB) that exposes endpoints to smart contracts deployed in a local developer environment, manages wallet accounts, and executes transactions. PAB utilizes Nix as a build tool and Haskell as a programming language within it's repository, which played a big part in influencing what tools were selected to build the other components of the Dapp.
This DApp is made possible using the IOHK's Plutus Application Backend(PAB) that exposes endpoints to smart contracts deployed in a local developer environment, manages wallet accounts, and executes transactions. PAB utilizes Nix as a build tool and Haskell as a programming language within its repository, which played a big part in influencing what tools were selected to build the other components of the DApp.

The frontend and middleware of this Dapp is made possible using Obelisk, a framework that allows you to build high-quality web and mobile applications. Obelisk shares the same build tool and programming language as PAB, Haskell and Nix. This makes communication between PAB and Obelisk pleasant when it comes to parsing data types, sharing data types, and deployment.
The frontend and middleware of this DApp is made possible using Obelisk, a framework that allows you to build high-quality web and mobile applications. Obelisk shares the same build tool and programming language as PAB, Haskell and Nix. This makes communication between PAB and Obelisk pleasant when it comes to parsing data types, sharing data types, and deployment.

By the end of this README you will be able to run the POKE-DEX on your machine locally and observe the behaviors of smart contracts against the Cardano mock chain by the power of PAB. Start by installing Obelisk, then running PAB, followed by running Obelisk as explained below

Expand All @@ -13,40 +13,52 @@ By the end of this README you will be able to run the POKE-DEX on your machine l
* Linux (i686, x86_64, aarch64).
* macOS (x86_64).

## Installing Obelisk
## Running the App

1. [Install Obelisk](https://github.com/obsidiansystems/obelisk#installing-obelisk).
1. **Install Obelisk** by following the instructions [here](https://github.com/obsidiansystems/obelisk#installing-obelisk).

## Running Plutus Application Backend (PAB)
1. **Optional: Add Nix caches**. Otherwise you will have to spend a very long time compiling things from source. The following includes both Obelisk and Cardano (IOHK) caches:
```nix
binaryCaches = [
"https://nixcache.reflex-frp.org"
"https://hydra.iohk.io"
"https://iohk.cachix.org"
];
binaryCachePublicKeys = [
"ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI="
"hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="
"iohk.cachix.org-1:DpRUyj7h7V830dp/i6Nti+NEO2/nhblbov/8MW7Rqoo="
];
```

1. [Run PAB] After installing Obelisk, use `./scripts/run-pab.sh` to launch the PAB and have it listen on port 8080
1. **Make sure you don't have anything running using port 8080**. You can check by running `netstat -nltp | grep ':8080'`; if you see something like `tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 1234/some-server-process`, that means the port is in use by `some-server-process`, and you will need to stop that process.

## Starting Obelisk Frontend
1. **Run PAB** in its own terminal window by `cd`ing to this directory and runing `./scripts/run-pab.sh`. Once it has started running, it will output something like `[INFO] Starting PAB backend server on port: 8080`, followed by many additional lines starting with `[INFO]`. You will need to leave the PAB running for as long as you are using the app; if the PAB shuts down for any reason, all chain data will be lost, and you will need to `rm -rf db` to clear the app state and then restart from this step.

1. After running the Plutus Application Backend, in a different terminal, run `ob run`
1. The frontend should be running on localhost:8000 when successful and visible via your browser.
1. **Run this App** in a separate terminal window by `cd`ing to this directory and running `ob run`. After a while, it will output lines starting with `"Pool tokens persisted:`, at which point the app is fully functional.

## Supported Browsers
1. Google Chrome
1. Chromium
1. **Open the App** in a Chrome or Chromium window (**not** Firefox, see [below](#development-mode-supported-browsers)), navigate to [http://localhost:8000](http://localhost:8000).

Note: Firefox can not run the app given that `ob run`(the only instructions provided to see the fronted) does not currently support this browser, app may appear to be broken.
## Development Mode Supported Browsers
`ob run` uses a lot of tricks to make development fast. Currently, it is only tested with Chrome-based browsers, such as Google Chrome and Chromium. Firefox does **not** work - typically the app will load, but then hang.

## Developing this Plutus Obelisk Dapp
Production deployments of the application should work in all major browsers, including Firefox.

## Developing this Plutus Obelisk DApp

Here are some useful tools and tips to get you started on developing and trouble shooting.
1. Diving into PAB and Smart Contract programming!
This application leverages a significant amount of Lar's Uniswap Smart Contract implementation thoroughly explained in the Plutus Pioneer Program. Here is a [video link](https://www.youtube.com/watch?v=Dg36h9YPMz4) in case you missed it!
This application leverages a significant amount of Lar's Uniswap Smart Contract implementation thoroughly explained in the Plutus Pioneer Program. Here is a [video link](https://www.youtube.com/watch?v=Dg36h9YPMz4) in case you missed it!

Some changes were made to the Smart Contract calls in order to provide more information to the frontend and to add other additional smart contract functionality. However, most of the modules and pure Uniswap functionality remained the same.

Assuming you've already installed the Obelisk command line tool, let's take a look what PAB is tasked with doing under the hood by running the following commands.
1. `ob thunk unpack dep/plutus-starter` will fetch the pinned version of plutus starter and replace a github .json file with the cloned plutus-starter repository
1. `cd dep/plutus-starter`
1. use your favorite text editor to open `pab/Main.hs` to inspect the source code of what PAB is running when launching this Dapp.
1. use your favorite text editor to open `pab/Main.hs` to inspect the source code of what PAB is running when launching this DApp.
1. Building and Running PAB in GHCI Repl
Now that you've used `ob thunk unpack` to get into `dep/plutus-starter`, from inside `dep/plutus-starter` you can get into a repl using the following commands:

```
$ nix-shell
$ cabal new-repl exe:plutus-starter-pab`
Expand All @@ -55,10 +67,10 @@ By the end of this README you will be able to run the POKE-DEX on your machine l

1. Developing the "App" Part of the "DApp"
Now that we've got PAB ready for action, let's return back to the top level of this Obelisk project (`plutus-use-cases/use-case-2`) and briefly go over this application's components.

- Backend components are found within the `backend` folder. In the architecture of this Dapp, the backend is responsible for communication directly with PAB via HTTP Request using JSON payloads that PAB's API endpoints are capable of performing smart contract operations with (If you're curious where PAB endpoints are constructed, take a peek at the `UniswapUserSchema` type located in `dep/plutus-starter/src/Plutus/Contracts/Uniswap/OffChain.hs`). Within `backend/src/Backend.hs` you will see request handlers that correspond to the smart contract operations endpoints which submit requests to PAB and parse PABs `observableState` JSON key in order to obtain PAB's response.
- Common components are found within the `common` folder. As of now this mostly consists of middleware, datatypes that are shared between the frontend and backend components, as well as datatypes that are shared with PAB (shared data types are to be removed in coming Obelisk updates).
- Frontend components are found within the `frontend` folder. This is where dom building, event handling, and API calls to `backend` components are taking place. The frontend is written using Reflex-FRP. The frontend fetches a significant amount of it's information about PAB's smart contract state via use of PAB's websocket and API endpoints via the websocket. Some interesting modules to look at are `frontend/src/Frontend.hs` and `frontend/src/Frontend/WebsocketParse.hs`.

1. Ok less talking, more poking user interfaces! While PAB is running and listening on port 8080, in a different terminal, run `ob run --no-interpret ./dep/plutus-starter`
This will start up an interactive repl that will refresh itself anytime you make changes to the 3 component folders I've mentioned above (frontend, common, and backend). If everything compiled, the Dapp should now be running on localhost:8000. Have fun!
- Server-side components are found within the `backend` folder. In the architecture of this DApp, the backend is responsible for communication directly with PAB via HTTP Request using JSON payloads that PAB's API endpoints are capable of performing smart contract operations with (If you're curious where PAB endpoints are constructed, take a peek at the `UniswapUserSchema` type located in `dep/plutus-starter/src/Plutus/Contracts/Uniswap/OffChain.hs`). Within `backend/src/Backend.hs` you will see request handlers that correspond to the smart contract operations endpoints which submit requests to PAB and parse PABs `observableState` JSON key in order to obtain PAB's response.
- In-browser components are found within the `frontend` folder. This is where HTML rendering, event handling, and API calls to `backend` components are taking place. The frontend is written using Reflex-FRP. The frontend fetches a significant amount of its information about PAB's smart contract state via use of PAB's websocket and API endpoints via the websocket. Some interesting modules to look at are `frontend/src/Frontend.hs` and `frontend/src/Frontend/WebsocketParse.hs`.
- Components shared between server-side and browser-side code are found within the `common` folder. As of now this mostly consists of middleware, datatypes that are shared between the frontend and backend components, as well as datatypes that are shared with PAB (shared data types are to be removed in coming Obelisk updates).

1. Ok! Less talking, more poking user interfaces! While PAB is running and listening on port 8080, in a different terminal, run `ob run --no-interpret ./dep/plutus-starter`
This will start up an interactive repl that will refresh itself anytime you make changes to the 3 component folders I've mentioned above (frontend, common, and backend). If everything compiled, the DApp should now be running on localhost:8000. Have fun!
1 change: 1 addition & 0 deletions use-case-2/backend/backend.cabal
Expand Up @@ -32,6 +32,7 @@ library
, rhyolite-backend
, rhyolite-backend-db
, rhyolite-backend-notification-postgres
, rhyolite-common
, scientific
, statistics
, text
Expand Down

0 comments on commit 3ed20ee

Please sign in to comment.