Skip to content

Commit

Permalink
SCP-3069: Simple demo app integrating Nami wallet with the PAB
Browse files Browse the repository at this point in the history
Co-authored-by: Jamie Bertram <jamie.bertram@tweag.io>
  • Loading branch information
koslambrou and jhbertra committed Dec 15, 2021
1 parent 835ce24 commit aa090e2
Show file tree
Hide file tree
Showing 50 changed files with 10,966 additions and 1 deletion.
9 changes: 9 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,15 @@ rec {
}) client server generate-purescript start-backend;
};

# TODO: Fails for now because of webpack can't include `nami-wallet` lib in it's bundle.
# To reproduce the error, run `npm run build:webpack:prod` in `plutus-pab/demo/pab-nami/client`
# pab-nami-demo = pkgs.recurseIntoAttrs rec {
# inherit (pkgs.callPackage ./plutus-pab/demo/pab-nami/client {
# inherit pkgs haskell webCommon;
# inherit (plutus-apps.lib) buildPursPackage buildNodeModules filterNpm gitignore-nix;
# }) client pab-setup-invoker pab-nami-demo-invoker;
# };

plutus-use-cases = pkgs.recurseIntoAttrs (pkgs.callPackage ./plutus-use-cases {
inherit haskell;
});
Expand Down
29 changes: 29 additions & 0 deletions nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-pab.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions nix/pkgs/haskell/materialized-darwin/default.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-pab.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions nix/pkgs/haskell/materialized-linux/default.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-pab.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions nix/pkgs/haskell/materialized-windows/default.nix

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 66 additions & 0 deletions plutus-pab/demo/pab-nami/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# PAB-Nami simple demo

This is a very simple demo application featuring the use of a browser/light wallet (Nami) alongside the PAB (Plutus Application Backend).

## Context

In this demo, we want to showcase a very minimal example of how to integrate the PAB with a light wallet. It uses the `PayToWallet` contract in the PAB which has *no* Plutus on-chain validation code. Therefore, we simply use the PAB to construct a partial/unbalanced transaction and make it available to a frontend application. It doesn't use a local Cardano node, nor the chain index. Here's an outline of the general interactions:

1. The frontend application should have access to a light/browser wallet (in this case, Nami)
2. The frontend application activates the `PayToWallet` contract throught the PAB.
3. The frontend application calls the `PayToWallet` contract PAB endpoint with the recipient's payment key hash and stake key hash, and the amount to send in Lovelace.
4. The PAB constructs a partial/unbalanced transaction and makes it available through it's contract instance's status endpoint.
5. The frontend application fetches this partial/unbalanced transaction. It then balances it and signs it using the Nami wallet api.
6. Finally, the frontend application submits the final transaction using the Nami wallet api (which in turn, uses the blockfrost API).

## Run the demo

The instructions were tested inside the `plutus-apps`'s `nix-shell`.

The demo contains two parts: the PAB application in `plutus-pab/demo/pab-nami/pab` and the frontend application in `plutus-pab/demo/pab-nami/client` which interacts with the PAB and the Nami wallet.

### Setup Nami wallet

1. Install the Nami wallet browser extension (currently, the Nami wallet is only available in Chrome-based browsers)
2. Setup your wallet password and seed phrase as required.
3. Create a second account in your wallet in order to test the demo.
4. In Nami wallet's `Settings > Network`, select the Cardano testnet.
5. Add some funds to your main account using the [Cardano faucet](https://testnets.cardano.org/en/testnets/cardano/tools/faucet/) (when you have finished using your test tokens, please return them to the faucet following the instructions in their website).
6.

### Run the PAB

From a command line interface, make sure you're in the root folder of the `plutus-apps` repository, and run the following commands:

```
# 'Migrate' command to initialise the PAB database.
$ cabal run plutus-pab:exe:plutus-pab-nami-demo -- migrate --config plutus-pab/demo/pab-nami/pab/config.yaml
# Run the PAB webserver
$ cabal run plutus-pab:exe:plutus-pab-nami-demo -- webserver --config plutus-pab/demo/pab-nami/pab/config.yaml
```

### Run the demo frontend

From another command line interface, run the following command to launch the frontend application:

```
$ cd plutus-pab/demo/pab-nami/client
# To install NPM dependencies
$ npm install
# To install Spago dependencies
$ spago install
# Run the dev server
$ npm run build:webpack:dev
```

Open the browser with the frontend application's URL (`http://localhost:8009`). You will see two fields: the recipient's Bech32 Cardano address and an amount to send to it in Lovelace. From the Nami wallet interface, change to your *second* account, click on the `Receive` tab, copy the shown Cardano address and paste it in the application's form. Then, go back to your *first* account which contains your funds. Choose a lovelace amount (minimum of 2_000_000 Lovelace) and click on `Make payment`. The application should show the transaction id that was submitted to the Cardano testnet. After waiting for a bit, you should see the funds change in Nami wallet's interface.

## Development

### Frontend

The frontend is written in Purescript. When inserting new dependencies in `spago.dhall`, run `spago install` and `spago2nix generate`. Don't forget to commit the file changes.
10 changes: 10 additions & 0 deletions plutus-pab/demo/pab-nami/client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/bower_components/
/node_modules/
/.pulp-cache/
/output/
/generated-docs/
/.psc-package/
/.psc*
/.purs*
/.psa*
/.spago
56 changes: 56 additions & 0 deletions plutus-pab/demo/pab-nami/client/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{ pkgs, gitignore-nix, haskell, webCommon, buildPursPackage, buildNodeModules, filterNpm }:
let
pab-nami-demo-invoker = haskell.packages.plutus-pab.components.exes.plutus-pab-nami-demo;

pab-setup-invoker = haskell.packages.plutus-pab.components.exes.plutus-pab-setup;

# TODO: Use the PS generator in the demo app
# generated-purescript = pkgs.runCommand "pab-nami-demo-purescript" { } ''
# mkdir $out
# ${pab-setup-invoker}/bin/plutus-pab-setup psgenerator $out
# ln -s ${../pab/config.yaml} plutus-pab.yaml
# ${pab-nami-demo-invoker}/bin/plutus-pab-nami-demo --config plutus-pab.yaml psapigenerator $out
# '';

# generate-purescript = pkgs.writeShellScriptBin "pab-nami-demo-generate-purs" ''
# generatedDir=./generated
# rm -rf $generatedDir
# $(nix-build ../default.nix -A marlowe-dashboard.pab-setup-invoker)/bin/plutus-pab-setup psgenerator $generatedDir
# $(nix-build ../default.nix -A marlowe-dashboard.marlowe-invoker)/bin/marlowe-pab --config plutus-pab.yaml psapigenerator $generatedDir
# '';

# start-backend = pkgs.writeShellScriptBin "marlowe-pab-server" ''
# echo "marlowe-pab-server: for development use only"
# $(nix-build ../default.nix --quiet --no-build-output -A marlowe-dashboard.marlowe-invoker)/bin/marlowe-pab --config plutus-pab.yaml all-servers
# '';

cleanSrc = gitignore-nix.gitignoreSource ./.;

nodeModules = buildNodeModules {
projectDir = filterNpm cleanSrc;
packageJson = ./package.json;
packageLockJson = ./package-lock.json;
githubSourceHashMap = { };
};

client = pkgs.lib.overrideDerivation
(buildPursPackage {
inherit pkgs nodeModules;
src = cleanSrc;
checkPhase = ''
node -e 'require("./output/Test.Main").main()'
'';
name = "pab-nami-demo";
extraSrcs = {
# web-common-marlowe = webCommonMarlowe;
# generated = generated-purescript;
};
spagoPackages = pkgs.callPackage ./spago-packages.nix { };
})
(_: {
WEB_COMMON_SRC = webCommon;
});
in
{
inherit client pab-nami-demo-invoker pab-setup-invoker;
}
7 changes: 7 additions & 0 deletions plutus-pab/demo/pab-nami/client/entry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*eslint-env node*/
/*global global*/
import './static/main.css';

import('./src/Main.purs')
.then(m => m.main())
.catch(err => console.log(err))
31 changes: 31 additions & 0 deletions plutus-pab/demo/pab-nami/client/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXXX-X"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag("js", new Date());
gtag(
"config",
"UA-XXXXXXXXX-X",
{
"anonymize_ip": true,
"custom_map": { "dimension1": "product" },
"product": "nami-demo"
}
);
</script>
<!-- Segment Analytics -->
<script>
!function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware"];analytics.factory=function(e){return function(){var t=Array.prototype.slice.call(arguments);t.unshift(e);analytics.push(t);return analytics}};for(var e=0;e<analytics.methods.length;e++){var key=analytics.methods[e];analytics[key]=analytics.factory(key)}analytics.load=function(key,e){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.src="https://cdn.segment.com/analytics.js/v1/" + key + "/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n);analytics._loadOptions=e};analytics.SNIPPET_VERSION="4.13.1";
analytics.load("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
analytics.page();
}}();
</script>
<script defer src="runtime.7e2a408ec34db1e18755.js"></script><script defer src="vendors.a032b1b05443fc0e131e.js"></script><script defer src="main.08f5117d6181c7cf9cc8.js"></script></head>
<body></body>
</html>
1 change: 1 addition & 0 deletions plutus-pab/demo/pab-nami/client/lib/nami-wallet
Submodule nami-wallet added at 350146
Loading

0 comments on commit aa090e2

Please sign in to comment.