Merge pull request #23 from Plutonomicon/rory/nix
Nixify the project setup
Nixify the project setup
node*.nix linguist-generated=true
spago-packages.nix linguist-generated=true
flake.lock linguist-generated=true
/.purs*
/.psa*
/.spago
/.spago2nix*
result
result-*
.envrc
.direnv
node_modules
.node
.node-cfg
SHELL := bash
.ONESHELL:
.PHONY: autogen-deps run-testnet-node run-testnet-ogmios
.SHELLFLAGS := -eu -o pipefail -c
autogen-deps:
spago2nix generate \
&& node2nix -l package-lock.json \
&& mv default.nix node2nix.nix \
&& git restore default.nix
run-testnet-node:
docker run --rm \
-e NETWORK=testnet \
-v "$$PWD"/.node/socket:/ipc \
-v "$$PWD"/.node/data:/data \
inputoutput/cardano-node:1.31.0
run-testnet-ogmios:
ogmios \
--node-socket "$$CARDANO_NODE_SOCKET_PATH" \
--node-config "$$CARDANO_NODE_CONFIG"
query-testnet-sync:
cardano-cli query tip --testnet-magic 1097911063
- Nami docs - https://github.com/Berry-Pool/nami-wallet
- cddl spec for alonzo - https://github.com/input-output-hk/cardano-ledger/blob/0738804155245062f05e2f355fadd1d16f04cd56/alonzo/impl/cddl-files/alonzo.cddl
## Environment setup
this project is currently not nix-ified.
in the meantime, here are the setup instructions to ensure a consistent environment:
1. install node 14.17.3 - recommend using [Node Version Manager](https://github.com/nvm-sh/nvm)
2. install Docker, using the recommended method for your Operating System
3. `npm i -g [email protected] [email protected]`
4. steps 3-16 are to set up the Cardano environment for the public testnet. Private testnets will require additional documentation. For these steps, work in a sibling directory:
5. `git clone [email protected]:mlabs-haskell/cardano-infrastructure.git`
6. `cd cardano-infrastructure`
7. `export CARDANO_NODE_SOCKET_PATH=$PWD/node/socket/node.socket`
8. `./node/start.sh`
9. Query the tip to see if the node is fully synced (in a new shell from `cardano-infrastructure`) `cardano-cli query tip --testnet-magic 1097911063 --socket node/socket/node.socket`
if the node is fully synced, you will see:
```
{ "epoch": 1005,
"hash": "162d6541cc5aa6b0e098add8fa08a94660a08b9463c0a86fcf84661b5f63375f",
"slot": 7232440,
"block": 322985,
"era": "Alonzo",
"syncProgress": "100.00"
}
```
## Setup and dev environment
In particular, `syncProgress` is the important part here.
Running `nix develop` in the root of the repository will place you in an development environment with all of the necessary executables, tools, config, etc... to:
10. continuing in your new shell, repeat step 7 to define `CARDANO_NODE_SOCKET_PATH` in your new shell, if it is not currently defined in this environment
- build the project or use the repl with `spago` (the Purescript project can also be built using Nix directly, e.g. `nix build`). All of the JS dependencies are also present through symlinked `node_modules`
- run a Cardano testnet node along with our fork of `ogmios`. **Note**: at the moment, only running a public testnet node is supported. In future iterations we will support more scenarios (mainnet, private testnet, etc...)
11. in `cardano-infrastructure` - copy the following files
- https://github.com/input-output-hk/plutus-apps/blob/main/plutus-pab/test-node/testnet/testnet-config.json
- https://github.com/input-output-hk/plutus-apps/blob/main/plutus-pab/test-node/testnet/testnet-byron-genesis.json
- https://github.com/input-output-hk/plutus-apps/blob/main/plutus-pab/test-node/testnet/testnet-shelley-genesis.json
There are a few Makefile targets provided for convenience, all of which require being in the Nix shell environment. `make run-testnet-node` starts the node in a Docker container and `make run-testnet-ogmios` starts our fork of `ogmios` with the correct flags (i.e. config and node socket locations). If you prefer to run these without `make`, the environment variables `CARDANO_NODE_SOCKET_PATH` and `CARDANO_NODE_CONFIG` are also exported in the shell pointing to the correct locations.
12. `export CARDANO_NODE_CONFIG=$PWD/config.json` (the `ogmios` command will automatically search for the genesis files as siblings to the config file)
13. `git clone [email protected]:mlabs-haskell/ogmios.git` (currently we use an Ogmios Fork for querying Utxo's and Datum from the Cardano network)
14. `cd ogmios`
15. `nix build --extra-experimental-features nix-command --extra-experimental-features flakes`
16. `./result/bin/ogmios --node-socket $CARDANO_NODE_SOCKET_PATH --node-config $CARDANO_NODE_CONFIG`
After starting the node, you can use `make query-testnet-sync` to check its sync status. If the node is fully synced, you will see:
```
{ "epoch": 1005,
"hash": "162d6541cc5aa6b0e098add8fa08a94660a08b9463c0a86fcf84661b5f63375f",
"slot": 7232440,
"block": 322985,
"era": "Alonzo",
"syncProgress": "100.00"
}
```
## Setup
In particular, `syncProgress` is the important part here.
This project is not currently using nix, setup depends on Node version 14.17.3, purescript version 0.13.8, spago version 0.20.1.
```
spago install
npm install
spago build
```
### Building the project & testing
The build output is a library which can be used in a browser frontend such as the example testbed linked above
You can run `nix build` to build the Purescript project. `nix build .#check.<SYSTEM>` will build the packages (in the future, once we have a public `ogmios` instance to test against, this will run the tests as well; `nix flake check` unfortunately won't work because we depend on haskell.nix projects). `npm run test` can be used to only run the test suite.
To check runtime behaviors currently, you can run `spago repl`, or you can write some javascript in `scratch.js` and run `node scratch.js`
### Updating the autogenerated Nix expressions
## Testing
Unfortunately, we rely on two projects that require autogenerated Nix code (`spago2nix` and `node2nix`). This means that it is possible for our declared dependencies to drift from the autogen Nix code we import in various places. If you add either a Purescript or JS dependency, make sure to run `make autogen-deps` from within the Nix shell to update the autogen Nix modules.
`npm run test` will run the test suite.
**Important**: If you add a dependency to the package.json, make sure to update the lockfile with `npm i --package-lock-only` _before_ entering a new dev shell, otherwise the `shellHook` will fail. You'll need to remove the existing symlinked `node_modules` to do this (for some reason `npm` will _still_ try to write to the `node_modules`, but will fail because they're symlinked to the Nix store).
## Architecture
So if we think of pab as a library instead of as a standalone process there are really just a few problems to consider:
(
import (
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
) {
src = ./.;
}
).defaultNix
{
"nodes": {
"HTTP": {
"flake": false,
"locked": {
"lastModified": 1451647621,
"narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=",
"owner": "phadej",
"repo": "HTTP",
"rev": "9bc0996d412fef1787449d841277ef663ad9a915",
"type": "github"
},
"original": {
"owner": "phadej",
"repo": "HTTP",
"type": "github"
}
},
"HTTP_2": {
"flake": false,
"locked": {
"lastModified": 1451647621,
"narHash": "sha256-oHIyw3x0iKBexEo49YeUDV1k74ZtyYKGR2gNJXXRxts=",
"owner": "phadej",
"repo": "HTTP",
"rev": "9bc0996d412fef1787449d841277ef663ad9a915",
"type": "github"
},
"original": {
"owner": "phadej",
"repo": "HTTP",
"type": "github"
}
},
"cabal-32": {
"flake": false,
"locked": {
"lastModified": 1603716527,
"narHash": "sha256-sDbrmur9Zfp4mPKohCD8IDZfXJ0Tjxpmr2R+kg5PpSY=",
"owner": "haskell",
"repo": "cabal",
"rev": "94aaa8e4720081f9c75497e2735b90f6a819b08e",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "3.2",
"repo": "cabal",
"type": "github"
}
},
"cabal-32_2": {
"flake": false,
"locked": {
"lastModified": 1603716527,
"narHash": "sha256-sDbrmur9Zfp4mPKohCD8IDZfXJ0Tjxpmr2R+kg5PpSY=",
"owner": "haskell",
"repo": "cabal",
"rev": "94aaa8e4720081f9c75497e2735b90f6a819b08e",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "3.2",
"repo": "cabal",
"type": "github"
}
},
"cabal-34": {
"flake": false,
"locked": {
"lastModified": 1622475795,
"narHash": "sha256-chwTL304Cav+7p38d9mcb+egABWmxo2Aq+xgVBgEb/U=",
"owner": "haskell",
"repo": "cabal",
"rev": "b086c1995cdd616fc8d91f46a21e905cc50a1049",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "3.4",
"repo": "cabal",
"type": "github"
}
},
"cabal-34_2": {
"flake": false,
"locked": {
"lastModified": 1622475795,
"narHash": "sha256-chwTL304Cav+7p38d9mcb+egABWmxo2Aq+xgVBgEb/U=",
"owner": "haskell",
"repo": "cabal",
"rev": "b086c1995cdd616fc8d91f46a21e905cc50a1049",
"type": "github"
},
"original": {
"owner": "haskell",
"ref": "3.4",
"repo": "cabal",
"type": "github"
}
},
"cardano-configurations": {
"flake": false,
"locked": {
"lastModified": 1634002394,
"narHash": "sha256-yqw88AbBjBa0VDwXz04+1gV3zXYAaS+/1PNowwmrsJ8=",
"owner": "input-output-hk",
"repo": "cardano-configurations",
"rev": "26b6b6de73f90e4777602b372798bf77addcc321",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "cardano-configurations",
"type": "github"
}
},
"cardano-node": {
"inputs": {
"customConfig": "customConfig",
"haskellNix": "haskellNix",
"iohkNix": "iohkNix",
"nixpkgs": [
"cardano-node",
"haskellNix",
"nixpkgs-2105"
],
"utils": "utils"
},
"locked": {
"lastModified": 1631803678,
"narHash": "sha256-8BFI16sQGE+ltlA7LcDnh/9V8xjuKcTUd09FyPs1p94=",
"owner": "input-output-hk",
"repo": "cardano-node",
"rev": "ea8b632820db5546b22430bbb5ed8db4a2fef7dd",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "cardano-node",
"rev": "ea8b632820db5546b22430bbb5ed8db4a2fef7dd",
"type": "github"
}
},
"cardano-shell": {
"flake": false,
"locked": {
"lastModified": 1608537748,
"narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=",
"owner": "input-output-hk",
"repo": "cardano-shell",
"rev": "9392c75087cb9a3d453998f4230930dea3a95725",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "cardano-shell",
"type": "github"
}
},
"cardano-shell_2": {
"flake": false,
"locked": {
"lastModified": 1608537748,
"narHash": "sha256-PulY1GfiMgKVnBci3ex4ptk2UNYMXqGjJOxcPy2KYT4=",
"owner": "input-output-hk",
"repo": "cardano-shell",
"rev": "9392c75087cb9a3d453998f4230930dea3a95725",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "cardano-shell",
"type": "github"
}
},
"customConfig": {
"locked": {
"lastModified": 1630400035,
"narHash": "sha256-MWaVOCzuFwp09wZIW9iHq5wWen5C69I940N1swZLEQ0=",
"owner": "input-output-hk",
"repo": "empty-flake",
"rev": "2040a05b67bf9a669ce17eca56beb14b4206a99a",
"type": "github"
},
"original": {
"owner": "input-output-hk",
"repo": "empty-flake",
"type": "github"
}
},
"easy-purescript-nix": {
"flake": false,
"locked": {
"lastModified": 1641236510,
"narHash": "sha256-JEabdJ+3cZEYDVnzgMH/YFsaGtIBiCFcgvVO9XRgiY4=",
"owner": "justinwoo",
"repo": "easy-purescript-nix",
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/release-21.11";
ogmios.url = "github:mlabs-haskell/ogmios";
cardano-node = {
type = "github";
owner = "input-output-hk";
repo = "cardano-node";
rev = "ea8b632820db5546b22430bbb5ed8db4a2fef7dd";
};
cardano-configurations = {
url = "github:input-output-hk/cardano-configurations";
flake = false;
};
easy-purescript-nix = {
url = "github:justinwoo/easy-purescript-nix";
flake = false;
};
flake-utils.url = "github:numtide/flake-utils";
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
};
outputs =
{ self
, nixpkgs
, ogmios
, cardano-node
, cardano-configurations
, easy-purescript-nix
, flake-utils
, ...
}@inputs:
flake-utils.lib.eachSystem
[ "x86_64-linux" "x86_64-darwin" ]
(
system:
let
pkgs = nixpkgs.legacyPackages.${system};
# We should try to use a consistent version of node across all
# project components
nodejs = pkgs.nodejs-12_x;
ps-lib = import ./nix/lib.nix {
inherit pkgs easy-ps spagoPkgs nodejs nodeModules;
};
easy-ps = import easy-purescript-nix { inherit pkgs; };
spagoPkgs = import ./spago-packages.nix { inherit pkgs; };
nodeModules =
let
modules = pkgs.callPackage
(_:
let
nodePkgs = import ./node2nix.nix {
inherit pkgs system nodejs;
};
in
nodePkgs // {
shell = nodePkgs.shell.override {
# see https://github.com/svanderburg/node2nix/issues/198
buildInputs = [ pkgs.nodePackages.node-gyp-build ];
};
});
in
(modules { }).shell.nodeDependencies;
in
{
defaultPackage = self.packages.${system}.cardano-browser-tx;
packages = {
cardano-browser-tx = ps-lib.buildPursProject {
name = "cardano-browser-tx";
src = ./.;
};
};
# NOTE
# Since we depend on two haskell.nix projects, `nix flake check`
# is currently broken because of IFD issues
checks = {
cardano-browser-tx = ps-lib.runPursTest {
name = "cardano-browser-tx";
src = ./.;
subdir = ".";
};
};
# TODO
# Once we have a public ogmios instance to test against,
# add `self.checks.${system}` to the `buildInputs`
check = pkgs.runCommand "combined-check"
{
nativeBuildInputs = builtins.attrValues self.packages.${system};
} "touch $out";
devShell = import ./nix/dev-shell.nix {
inherit pkgs system inputs nodeModules easy-ps nodejs;
};
}
);
}
{ pkgs
, system
, inputs
, nodeModules
, easy-ps
, nodejs
, compiler ? easy-ps.purs-0_14_5
, ...
}:
with inputs;
pkgs.mkShell {
buildInputs = with easy-ps; [
ogmios.packages.${system}."ogmios:exe:ogmios"
cardano-node.packages.${system}.cardano-cli
compiler
spago
purescript-language-server
purty
spago2nix
pkgs.nodePackages.node2nix
nodejs
];
shellHook = ''
__ln-node-modules () {
if test -L node_modules; then
rm node_modules;
elif test -e node_modules; then
echo 'refusing to overwrite existing (non-symlinked) `node_modules`'
exit 1
fi
ln -s ${nodeModules}/lib/node_modules node_modules
}
__ln-testnet-config () {
local cfgdir=./.node-cfg
if test -e "$cfgdir"; then
rm -r "$cfgdir"
fi
mkdir -p "$cfgdir"/testnet/{config,genesis}
ln -s ${cardano-configurations}/network/testnet/cardano-node/config.json \
"$cfgdir"/testnet/config/config.json
ln -s ${cardano-configurations}/network/testnet/genesis/byron.json \
"$cfgdir"/testnet/genesis/byron.json
ln -s ${cardano-configurations}/network/testnet/genesis/shelley.json \
"$cfgdir"/testnet/genesis/shelley.json
}
__ln-node-modules
__ln-testnet-config
export NODE_PATH="$PWD/node_modules:$NODE_PATH"
export CARDANO_NODE_SOCKET_PATH="$PWD"/.node/socket/node.socket
export CARDANO_NODE_CONFIG="$PWD"/.node-cfg/testnet/config/config.json
'';
}
{ pkgs
, easy-ps
, spagoPkgs
, nodejs
, compiler ? easy-ps.purs-0_14_5
, nodeModules
, ...
}:
rec {
buildPursProject = { name, src, subdir ? "src" }:
pkgs.stdenv.mkDerivation {
inherit name src;
buildInputs = [
spagoPkgs.installSpagoStyle
spagoPkgs.buildSpagoStyle
];
nativeBuildInputs = [
compiler
easy-ps.spago
];
buildPhase = ''
export HOME="$TMP"
cp -r ${nodeModules}/lib/node_modules .
chmod -R u+rw node_modules
cp $src/spago.dhall .
cp $src/packages.dhall .
cp -r $src/${subdir} .
install-spago-style
build-spago-style "./${subdir}/**/*.purs"
'';
installPhase = ''
mkdir $out
mv output $out/
'';
};
runPursTest = { name, ... }@args:
(buildPursProject args).overrideAttrs
(oldAttrs: {
name = "${name}-check";
doCheck = true;
buildInputs = oldAttrs.buildInputs ++ [ nodejs ];
# spago will attempt to download things, which will fail in the
# sandbox (idea taken from `plutus-playground-client`)
checkPhase = ''
node -e 'require("./output/Test.Main").main()'
'';
installPhase = ''
touch $out
'';
});
bundlePursProject = { name, ... }@args:
(buildPursProject args).overrideAttrs
(oldAttrs: {
name = "${name}-bundled";
installPhase = ''
spago bundle-module --no-install --no-build --to $out/index.js
'';
});
}
# This file originates from node2nix
{lib, stdenv, nodejs, python2, pkgs, libtool, runCommand, writeTextFile, writeShellScript}:
let
# Workaround to cope with utillinux in Nixpkgs 20.09 and util-linux in Nixpkgs master
utillinux = if pkgs ? utillinux then pkgs.utillinux else pkgs.util-linux;
python = if nodejs ? python then nodejs.python else python2;
# Create a tar wrapper that filters all the 'Ignoring unknown extended header keyword' noise
tarWrapper = runCommand "tarWrapper" {} ''
mkdir -p $out/bin
cat > $out/bin/tar <<EOF
#! ${stdenv.shell} -e
$(type -p tar) "\[email protected]" --warning=no-unknown-keyword --delay-directory-restore
EOF
chmod +x $out/bin/tar
'';
# Function that generates a TGZ file from a NPM project
buildNodeSourceDist =
{ name, version, src, ... }:
stdenv.mkDerivation {
name = "node-tarball-${name}-${version}";
inherit src;
buildInputs = [ nodejs ];
buildPhase = ''
export HOME=$TMPDIR
tgzFile=$(npm pack | tail -n 1) # Hooks to the pack command will add output (https://docs.npmjs.com/misc/scripts)
'';
installPhase = ''
mkdir -p $out/tarballs
mv $tgzFile $out/tarballs
mkdir -p $out/nix-support
echo "file source-dist $out/tarballs/$tgzFile" >> $out/nix-support/hydra-build-products
'';
};
# Common shell logic
installPackage = writeShellScript "install-package" ''
installPackage() {
local packageName=$1 src=$2
local strippedName
local DIR=$PWD
cd $TMPDIR
unpackFile $src
# Make the base dir in which the target dependency resides first
mkdir -p "$(dirname "$DIR/$packageName")"
if [ -f "$src" ]
then
# Figure out what directory has been unpacked
packageDir="$(find . -maxdepth 1 -type d | tail -1)"
# Restore write permissions to make building work
find "$packageDir" -type d -exec chmod u+x {} \;
chmod -R u+w "$packageDir"
# Move the extracted tarball into the output folder
mv "$packageDir" "$DIR/$packageName"
elif [ -d "$src" ]
then
# Get a stripped name (without hash) of the source directory.
# On old nixpkgs it's already set internally.
if [ -z "$strippedName" ]
then
strippedName="$(stripHash $src)"
fi
# Restore write permissions to make building work
chmod -R u+w "$strippedName"
# Move the extracted directory into the output folder
mv "$strippedName" "$DIR/$packageName"
fi
# Change to the package directory to install dependencies
cd "$DIR/$packageName"
}
'';
# Bundle the dependencies of the package
#
# Only include dependencies if they don't exist. They may also be bundled in the package.
includeDependencies = {dependencies}:
lib.optionalString (dependencies != []) (
''
mkdir -p node_modules
cd node_modules
''
+ (lib.concatMapStrings (dependency:
''
if [ ! -e "${dependency.name}" ]; then
${composePackage dependency}
fi
''
) dependencies)
+ ''
cd ..
''
);
# Recursively composes the dependencies of a package
composePackage = { name, packageName, src, dependencies ? [], ... }@args:
builtins.addErrorContext "while evaluating node package '${packageName}'" ''
installPackage "${packageName}" "${src}"
${includeDependencies { inherit dependencies; }}
cd ..
${lib.optionalString (builtins.substring 0 1 packageName == "@") "cd .."}
'';
pinpointDependencies = {dependencies, production}:
let
pinpointDependenciesFromPackageJSON = writeTextFile {
name = "pinpointDependencies.js";
text = ''
var fs = require('fs');
var path = require('path');
function resolveDependencyVersion(location, name) {
if(location == process.env['NIX_STORE']) {
return null;
} else {
var dependencyPackageJSON = path.join(location, "node_modules", name, "package.json");
if(fs.existsSync(dependencyPackageJSON)) {
var dependencyPackageObj = JSON.parse(fs.readFileSync(dependencyPackageJSON));
if(dependencyPackageObj.name == name) {
return dependencyPackageObj.version;
}
} else {
return resolveDependencyVersion(path.resolve(location, ".."), name);
}
}
}
function replaceDependencies(dependencies) {
if(typeof dependencies == "object" && dependencies !== null) {
for(var dependency in dependencies) {
var resolvedVersion = resolveDependencyVersion(process.cwd(), dependency);
if(resolvedVersion === null) {
process.stderr.write("WARNING: cannot pinpoint dependency: "+dependency+", context: "+process.cwd()+"\n");
} else {
dependencies[dependency] = resolvedVersion;
}
}
}
}
/* Read the package.json configuration */
var packageObj = JSON.parse(fs.readFileSync('./package.json'));
/* Pinpoint all dependencies */
replaceDependencies(packageObj.dependencies);
if(process.argv[2] == "development") {
replaceDependencies(packageObj.devDependencies);
}
replaceDependencies(packageObj.optionalDependencies);
/* Write the fixed package.json file */
fs.writeFileSync("package.json", JSON.stringify(packageObj, null, 2));
'';
};
in
''
node ${pinpointDependenciesFromPackageJSON} ${if production then "production" else "development"}
${lib.optionalString (dependencies != [])
''
if [ -d node_modules ]
then
cd node_modules
${lib.concatMapStrings (dependency: pinpointDependenciesOfPackage dependency) dependencies}
cd ..
fi
''}
'';
# Recursively traverses all dependencies of a package and pinpoints all
# dependencies in the package.json file to the versions that are actually
# being used.
pinpointDependenciesOfPackage = { packageName, dependencies ? [], production ? true, ... }@args:
''
if [ -d "${packageName}" ]
then
cd "${packageName}"
${pinpointDependencies { inherit dependencies production; }}
cd ..
# This file has been generated by node2nix 1.9.0. Do not edit!
{nodeEnv, fetchurl, fetchgit, nix-gitignore, stdenv, lib, globalBuildInputs ? []}:
let
sources = {
"@cardano-ogmios/client-4.2.1" = {
name = "_at_cardano-ogmios_slash_client";
packageName = "@cardano-ogmios/client";
version = "4.2.1";
src = fetchurl {
url = "https://registry.npmjs.org/@cardano-ogmios/client/-/client-4.2.1.tgz";
sha512 = "CiScFBqOeMZtFLN67jUqsiad4xIoW17TIt+QfZlgpX5nTHHjs1kTuoNYN088dICrBy7M6EvkETQBJLwK/BR83Q==";
};
};
"@cardano-ogmios/schema-4.2.1" = {
name = "_at_cardano-ogmios_slash_schema";
packageName = "@cardano-ogmios/schema";
version = "4.2.1";
src = fetchurl {
url = "https://registry.npmjs.org/@cardano-ogmios/schema/-/schema-4.2.1.tgz";
sha512 = "XRiew+YFeat/cfXAdjwWXux+agRGA5SzD0VCYXnZ9OtxgjyApwXxpbGFLeGxuz7FyMlAKimS88fq37dJPacS1Q==";
};
};
"@cardanosolutions/json-bigint-1.0.0" = {
name = "_at_cardanosolutions_slash_json-bigint";
packageName = "@cardanosolutions/json-bigint";
version = "1.0.0";
src = fetchurl {
url = "https://registry.npmjs.org/@cardanosolutions/json-bigint/-/json-bigint-1.0.0.tgz";
sha512 = "46ts2s0W63nzqHMhaXKACeY0GDWdnPet9wqOWtb8X3Y5LzokcaDKupLO2eHUwlvQyFzD9gxJlWPi/LqZPkn4oQ==";
};
};
"@types/json-bigint-1.0.1" = {
name = "_at_types_slash_json-bigint";
packageName = "@types/json-bigint";
version = "1.0.1";
src = fetchurl {
url = "https://registry.npmjs.org/@types/json-bigint/-/json-bigint-1.0.1.tgz";
sha512 = "zpchZLNsNuzJHi6v64UBoFWAvQlPhch7XAi36FkH6tL1bbbmimIF+cS7vwkzY4u5RaSWMoflQfu+TshMPPw8uw==";
};
};
"big-integer-1.6.51" = {
name = "big-integer";
packageName = "big-integer";
version = "1.6.51";
src = fetchurl {
url = "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz";
sha512 = "GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==";
};
};
"bignumber.js-9.0.2" = {
name = "bignumber.js";
packageName = "bignumber.js";
version = "9.0.2";
src = fetchurl {
url = "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.2.tgz";
sha512 = "GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==";
};
};
"bufferutil-4.0.5" = {
name = "bufferutil";
packageName = "bufferutil";
version = "4.0.5";
src = fetchurl {
url = "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.5.tgz";
sha512 = "HTm14iMQKK2FjFLRTM5lAVcyaUzOnqbPtesFIvREgXpJHdQm8bWS+GkQgIkfaBYRHuCnea7w8UVNfwiAQhlr9A==";
};
};
"cross-fetch-3.1.4" = {
name = "cross-fetch";
packageName = "cross-fetch";
version = "3.1.4";
src = fetchurl {
url = "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz";
sha512 = "1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==";
};
};
"fastq-1.13.0" = {
name = "fastq";
packageName = "fastq";
version = "1.13.0";
src = fetchurl {
url = "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz";
sha512 = "YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==";
};
};
"isomorphic-ws-4.0.1" = {
name = "isomorphic-ws";
packageName = "isomorphic-ws";
version = "4.0.1";
src = fetchurl {
url = "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz";
sha512 = "BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==";
};
};
"nanoid-3.1.30" = {
name = "nanoid";
packageName = "nanoid";
version = "3.1.30";
src = fetchurl {
url = "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz";
sha512 = "zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==";
};
};
"node-fetch-2.6.1" = {
name = "node-fetch";
packageName = "node-fetch";
version = "2.6.1";
src = fetchurl {
url = "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz";
sha512 = "V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==";
};
};
"node-gyp-build-4.3.0" = {
name = "node-gyp-build";
packageName = "node-gyp-build";
version = "4.3.0";
src = fetchurl {
url = "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.3.0.tgz";
sha512 = "iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q==";
};
};
"reusify-1.0.4" = {
name = "reusify";
packageName = "reusify";
version = "1.0.4";
src = fetchurl {
url = "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz";
sha512 = "U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==";
};
};
"ts-custom-error-3.2.0" = {
name = "ts-custom-error";
packageName = "ts-custom-error";
version = "3.2.0";
src = fetchurl {
url = "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.2.0.tgz";
sha512 = "cBvC2QjtvJ9JfWLvstVnI45Y46Y5dMxIaG1TDMGAD/R87hpvqFL+7LhvUDhnRCfOnx/xitollFWWvUKKKhbN0A==";
};
};
"uniqid-5.4.0" = {
name = "uniqid";
packageName = "uniqid";
version = "5.4.0";
src = fetchurl {
url = "https://registry.npmjs.org/uniqid/-/uniqid-5.4.0.tgz";
sha512 = "38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A==";
};
};
"ws-7.5.6" = {
name = "ws";
packageName = "ws";
version = "7.5.6";
src = fetchurl {
url = "https://registry.npmjs.org/ws/-/ws-7.5.6.tgz";
sha512 = "6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA==";
};
};
"ws-8.4.0" = {
name = "ws";
packageName = "ws";
version = "8.4.0";
src = fetchurl {
url = "https://registry.npmjs.org/ws/-/ws-8.4.0.tgz";
sha512 = "IHVsKe2pjajSUIl4KYMQOdlyliovpEPquKkqbwswulszzI7r0SfQrxnXdWAEqOlDCLrVSJzo+O1hAwdog2sKSQ==";
};
};
};
args = {
name = "realpab";
packageName = "realpab";
version = "1.0.0";
src = ./.;
dependencies = [
(sources."@cardano-ogmios/client-4.2.1" // {
dependencies = [
sources."ws-7.5.6"
];
})
sources."@cardano-ogmios/schema-4.2.1"
sources."@cardanosolutions/json-bigint-1.0.0"
sources."@types/json-bigint-1.0.1"
sources."big-integer-1.6.51"
sources."bignumber.js-9.0.2"
sources."bufferutil-4.0.5"
sources."cross-fetch-3.1.4"
sources."fastq-1.13.0"
sources."isomorphic-ws-4.0.1"
sources."nanoid-3.1.30"
sources."node-fetch-2.6.1"
sources."node-gyp-build-4.3.0"
sources."reusify-1.0.4"
sources."ts-custom-error-3.2.0"
sources."uniqid-5.4.0"
sources."ws-8.4.0"
];
buildInputs = globalBuildInputs;
meta = {
# This file has been generated by node2nix 1.9.0. Do not edit!
{pkgs ? import <nixpkgs> {
inherit system;
}, system ? builtins.currentSystem, nodejs ? pkgs."nodejs-12_x"}:
let
nodeEnv = import ./node-env.nix {
inherit (pkgs) stdenv lib python2 runCommand writeTextFile writeShellScript;
inherit pkgs nodejs;
libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
};
in
import ./node-packages.nix {
inherit (pkgs) fetchurl nix-gitignore stdenv lib fetchgit;
inherit nodeEnv;
}
"resolved": "https://registry.npmjs.org/uniqid/-/uniqid-5.4.0.tgz",
"integrity": "sha512-38JRbJ4Fj94VmnC7G/J/5n5SC7Ab46OM5iNtSstB/ko3l1b5g7ALt4qzHFgGciFkyiRNtDXtLNb+VsxtMSE77A=="
},
"utf-8-validate": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.7.tgz",
"integrity": "sha512-vLt1O5Pp+flcArHGIyKEQq883nBt8nN8tVBcoL0qUXj2XT1n7p70yGIq2VK98I5FdZ1YHc0wk/koOnHjnXWk1Q==",
"requires": {
"node-gyp-build": "^4.3.0"
}
},
"ws": {
"version": "8.4.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.4.0.tgz",
"big-integer": "^1.6.51",
"bufferutil": "^4.0.5",
"uniqid": "^5.4.0",
"utf-8-validate": "^5.0.7",
"ws": "^8.4.0"
}
}
-------------------------------
-}
let upstream =
https://github.com/purescript/package-sets/releases/download/psc-0.14.5-20211116/packages.dhall sha256:7e973070e323137f27e12af93bc2c2f600d53ce4ae73bb51f34eb7d7ce0a43ea
https://github.com/purescript/package-sets/releases/download/psc-0.14.5-20211116/packages.dhall sha256:7ba810597a275e43c83411d2ab0d4b3c54d0b551436f4b1632e9ff3eb62e327a
let additions =
{ tree =
{ dependencies = [ "console", "lists", "prelude", "free" ]
, repo = "https://github.com/dmbfm/purescript-tree.git"
, version = "v1.3.2"
}
, mote =
{ mote =
{ dependencies = [ "these", "transformers", "arrays" ]
, repo = "https://github.com/garyb/purescript-mote"
, version = "v1.1.0"
}
, quickcheck-combinators =
{ dependencies = [ "prelude", "quickcheck", "typelevel" ]
, repo =
"https://github.com/athanclark/purescript-quickcheck-combinators.git"
, version = "v0.1.2"
}
, medea =
{ dependencies =
[ "aff"
, "argonaut"
, "console"
, "arrays"
, "bifunctors"
, "control"
, "debug"
, "effect"
, "either"
, "enums"
, "exceptions"
, "foldable-traversable"
, "foreign-object"
, "free"
, "generics-rep"
, "lcg"
, "leibniz"
, "integers"
, "lists"
, "maybe"
, "mote"
, "naturals"
, "newtype"
, "node-buffer"
, "node-fs-aff"
, "node-path"
, "nonempty"
, "ordered-collections"
, "parallel"
, "parsing"
, "partial"
, "prelude"
, "psci-support"
, "quickcheck"
, "quickcheck-combinators"
, "safely"
, "spec"
, "strings"
, "these"
, "transformers"
, "tree"
, "typelevel"
, "tuples"
, "unicode"
, "unordered-collections"
, "unsafe-coerce"
]
, repo = "ssh://[email protected]/juspay/medea-ps.git"
, version = "96a93df8d4b7cc13b080ace299c195e61aad0cb8"
, repo = "https://github.com/juspay/medea-ps.git"
, version = "8b215851959aa8bbf33e6708df6bd683c89d1a5a"
}
}
(
import (
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
in
fetchTarball {
url = "https://github.com/edolstra/flake-compat/archive/${lock.nodes.flake-compat.locked.rev}.tar.gz";
sha256 = lock.nodes.flake-compat.locked.narHash;
}
) {
src = ./.;
}
).shellNix.default
# This file was generated by Spago2Nix
{ pkgs ? import <nixpkgs> {} }:
let
inputs = {
"aff" = pkgs.stdenv.mkDerivation {
name = "aff";
version = "v6.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript-contrib/purescript-aff.git";
rev = "d0eb009f2f47cb1f5ba1d8592d90c95e8e7ff75d";
sha256 = "1780sgqyvbdgh8ynxmxn5d44vvhaz7kn9sv3l44c2s9q8xfjkfgm";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"ansi" = pkgs.stdenv.mkDerivation {
name = "ansi";
version = "v6.1.0";
src = pkgs.fetchgit {
url = "https://github.com/hdgarrood/purescript-ansi.git";
rev = "e89e6fede616bd16b001841cf30ac320c95313a6";
sha256 = "1jsll0h7nz13zgscs036cnkkc6frnlcnk6fwjdwsyp6wbmjri2zm";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"argonaut" = pkgs.stdenv.mkDerivation {
name = "argonaut";
version = "v8.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript-contrib/purescript-argonaut.git";
rev = "e5137df76065c14e5de70c4e2820222bd7c78fc2";
sha256 = "05sq1102rl1phm2gadx0gp966yvk9q1r492bb30q1m0nz762q4v2";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"argonaut-codecs" = pkgs.stdenv.mkDerivation {
name = "argonaut-codecs";
version = "v8.1.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript-contrib/purescript-argonaut-codecs.git";
rev = "b0a041d92bfd548e2cd793cc7c02363464325a13";
sha256 = "11vmlq98s4jmg5grvdrrlfkqj9vk3la44ky8158a440ipcpinjkq";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"argonaut-core" = pkgs.stdenv.mkDerivation {
name = "argonaut-core";
version = "v6.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript-contrib/purescript-argonaut-core.git";
rev = "673971dee79667882a83f9fda7097e50530726f1";
sha256 = "13ka4xybc8ql54xlkkhy4919nnapfigdlk51ja85f8xwhr64x9kq";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"argonaut-traversals" = pkgs.stdenv.mkDerivation {
name = "argonaut-traversals";
version = "v9.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript-contrib/purescript-argonaut-traversals.git";
rev = "36f2e368ceea1ed681bd8e2884eaca451945fc44";
sha256 = "0bj88s7rz50jfhyawq4h97lvbr3h7pksbqnz4lmh714f5fda6ncx";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"arraybuffer-types" = pkgs.stdenv.mkDerivation {
name = "arraybuffer-types";
version = "v3.0.1";
src = pkgs.fetchgit {
url = "https://github.com/purescript-contrib/purescript-arraybuffer-types.git";
rev = "48cd7f4887791db1d9c2daf5fd98b62ba00e15bd";
sha256 = "09r6bhsiq9iqdsjf9p8m3p31qkszsipsafvy836mfdi8af6h5fv6";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"arrays" = pkgs.stdenv.mkDerivation {
name = "arrays";
version = "v6.0.1";
src = pkgs.fetchgit {
url = "https://github.com/purescript/purescript-arrays.git";
rev = "c0aa3176b077ad7a46b11ef34487485c28142e53";
sha256 = "0lm0m5hapimchzgfywr648pkw1hpggr6qibh8d19p2impbnc94c0";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"avar" = pkgs.stdenv.mkDerivation {
name = "avar";
version = "v4.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript-contrib/purescript-avar.git";
rev = "ac3cbbb8d4b71ff19a78a3178355c089e44d3b4d";
sha256 = "005046wl61w6r5v3qwd16srhcx82vdz3yvp4xzad2xaasb6iq55l";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"bifunctors" = pkgs.stdenv.mkDerivation {
name = "bifunctors";
version = "v5.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript/purescript-bifunctors.git";
rev = "a31d0fc4bbebf19d5e9b21b65493c28b8d3fba62";
sha256 = "0xc2hf8ccdgqw3m9qcmr38kmzv05fsxvakd07wyrqshvkzg3xn0d";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"bigints" = pkgs.stdenv.mkDerivation {
name = "bigints";
version = "v6.0.0";
src = pkgs.fetchgit {
url = "https://github.com/sharkdp/purescript-bigints.git";
rev = "d5151e04db7e18641fbb2b5892f4198b1cab5907";
sha256 = "0x8s6d6q2rpfkk56bmayg57a7hl2h7sq9ljrxfc8sjnwd7mfs193";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"catenable-lists" = pkgs.stdenv.mkDerivation {
name = "catenable-lists";
version = "v6.0.1";
src = pkgs.fetchgit {
url = "https://github.com/purescript/purescript-catenable-lists.git";
rev = "ee03395f2c5d59a7fd8529a0faac6ec1ebcbb682";
sha256 = "1lz06fx0za5sl65wccn5fl37mw3x4jnvrriz1gg0aqsmm9lag7ss";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"console" = pkgs.stdenv.mkDerivation {
name = "console";
version = "v5.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript/purescript-console.git";
rev = "d7cb69ef8fed8a51466afe1b623868bb29e8586e";
sha256 = "0fzzzqjgrz33pb2jf7cdqpg09ilxb7bsrc7sbfq52wjg0sx9aq6g";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"const" = pkgs.stdenv.mkDerivation {
name = "const";
version = "v5.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript/purescript-const.git";
rev = "3a3a4bdc44f71311cf27de9bd22039b110277540";
sha256 = "0aq9qjbrvf8mf8hmas6imv4mg6n3zi13hkf449ns1hn12lw8qv4g";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"contravariant" = pkgs.stdenv.mkDerivation {
name = "contravariant";
version = "v5.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript/purescript-contravariant.git";
rev = "ae1a765f7ddbfd96ae1f12e399e46d554d8e3b38";
sha256 = "029hb8i3n4759x4gc06wkfgr7wim5x1w5jy2bsiy42n0g731h5qc";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
"control" = pkgs.stdenv.mkDerivation {
name = "control";
version = "v5.0.0";
src = pkgs.fetchgit {
url = "https://github.com/purescript/purescript-control.git";
rev = "18d582e311f1f8523f9eb55fb93c91bd21e22837";
sha256 = "06dc06yli4g5yr8fb9sdpqbhiaff37g977qcsbds9q2mlhnjgfx9";
};
phases = "installPhase";
installPhase = "ln -s $src $out";
};
, "argonaut"
, "bigints"
, "console"
, "const"
, "control"
, "debug"
, "either"
, "effect"
, "exceptions"
, "foldable-traversable"
, "foreign-object"
, "generics-rep"
, "identity"
, "int-53"
, "maybe"
, "medea"
, "mote"
, "refs"
, "spec"
, "strings"
, "transformers"
, "transformers"
, "tuples"
, "undefined"
]
, packages = ./packages.dhall
, sources = [ "src/**/*.purs", "test/**/*.purs" ]
, sources =
[ "src/**/*.purs"
, "test/**/*.purs"
]
}
import Data.BigInt as BigInt
import Data.Either(Either(..), hush, note)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Show.Generic (genericShow)
import Data.Maybe (Maybe)
import Data.Int53 as Int
import Data.Foldable (foldl)
import Data.Map as Map
import Effect (Effect)
parseFieldToString o str =
caseJsonString (Left (TypeMismatch ("expected field: '" <> str <> "' as a String"))) Right =<< getField o str
-- parses the number at the given field to a 53 bit signed integer
-- parses the number at the given field to a bigint
-- danger: Because argonaut has already parsed this as a Json foreign, it may
-- already be a javascript 'number' type. if that number is not safely representable
-- then we may have already lost precision. we may need a bigint preprocessor on json if this is the case: Because argonaut has already parsed this as a Json foreign, it may
-- already be a javascript 'number' type. if that number is not safely representable
-- then we may have already lost precision. we may need a bigint preprocessor on json if this is the case.
parseFieldToInt :: Object Json -> String -> Either JsonDecodeError Int.Int53
parseFieldToInt :: Object Json -> String -> Either JsonDecodeError BigInt.BigInt
parseFieldToInt o str = do
let err = TypeMismatch $ "expected field: '" <> str <> "' as an Int"
num <- caseJsonNumber (Left err) Right =<< getField o str
int <- note err $ Int.fromNumber num
int <- note err $ BigInt.fromNumber num
pure int
-- parses a string at the given field to a BigInt
-- TxOutRef
type TxOutRef =
{ txId :: String,
index :: Int.Int53
index :: BigInt.BigInt
}
parseUtxoQueryResult :: Json -> Either JsonDecodeError UtxoQueryResult
parseValue :: Object Json -> Either JsonDecodeError Value
parseValue outer = do
o <- getField outer "value"
coins <- parseFieldToBigInt o "coins" <|> (convertIntParsing $ parseFieldToInt o "coins") <|> Left (TypeMismatch "Expected 'coins' to be an Int or a BigInt")
coins <- parseFieldToBigInt o "coins" <|> (parseFieldToInt o "coins") <|> Left (TypeMismatch "Expected 'coins' to be an Int or a BigInt")
(assetsJson :: {}) <- getField o "assets"
-- note 'coins' is being sent as a number, in some cases this may exceed the max safe
-- representation of a Number, we may need to parse this up from a string instead of from
-- assets are currently assumed to be empty
-- newtype Value = Value (Map CurrencySymbol (Map TokenName BigInt.BigInt))
pure $ Value $ Map.singleton (CurrencySymbol "") (Map.singleton (TokenName "") coins)
convertIntParsing
:: Either JsonDecodeError Int.Int53
-> Either JsonDecodeError BigInt.BigInt
convertIntParsing (Left e) = Left e
convertIntParsing (Right i) = do
note (TypeMismatch "unexpected conversion failure from Int to BigInt") $ BigInt.fromString $ Int.toString i
import Data.Tuple.Nested ((/\), type (/\))
import Data.Map (Map(..))
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Show (genericShow)
import Data.Show.Generic (genericShow)
newtype Transaction = Transaction {
body :: TxBody,
Other small changes include: * Added a trace event `TDBInitialisingFromLMDBDone`. * Initialisation from an existing LMDB database does not rely on the default `LMDBLimits` anymore, and is passed a limits argument instead. TODO: We should decide whether we want to hardcode these limits to a a substantially large one, or possibly we could link these limits to a versioning number?
add cwbtc
attempt implementation
Other small changes include: * Added a trace event `TDBInitialisingFromLMDBDone`. * Initialisation from an existing LMDB database does not rely on the default `LMDBLimits` anymore, and is passed a limits argument instead. TODO: We should decide whether we want to hardcode these limits to a a substantially large one, or possibly we could link these limits to a versioning number?
Updated crypto exchange rates chapter. I tried my best to address @rdlrt concerns. I would like to add that English is just my 3rd language, so I hope it is not too bad.
Previously, the sequence number of the database is written to disk as part of the on-disk database settings on every flush/write. Conceptually however, the settings of a database should not change on every flush or write. Instead, we make a dinstinction between on-disk database "settings" and "state", where the state can be updated in every write/flush, but the settings should generally be left untouched after database initialisation or node start-up.
Fixes #217.
This works because (a) JavaScript is ultimately single-threaded, (b) there's no execution preemption happening between a 'send' and a 'wait'.
This was using the raw Show instance of queries, which looks real bad for constructors with arity > 1 like HasTx.