Merge branch 'master' into naive/roller

This commit is contained in:
fang 2021-10-26 20:46:32 +02:00
commit 0ec3d5111d
No known key found for this signature in database
GPG Key ID: EB035760C1BBA972
1566 changed files with 140270 additions and 22490 deletions

5
.gitattributes vendored
View File

@ -3,4 +3,9 @@ bin/*/* filter=lfs diff=lfs merge=lfs -text
pkg/arvo/**/*.css binary
pkg/arvo/app/naive/logs.eth-logs filter=lfs diff=lfs merge=lfs -text
**/package-lock.json binary merge=theirs
pkg/arvo/tmp/garden.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/landscape.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/base.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/bitcoin.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/webterm.jam filter=lfs diff=lfs merge=lfs -text

View File

@ -116,3 +116,24 @@ jobs:
- run: nix-build -A hs.urbit-king.components.exes.urbit-king --arg enableStatic true
- run: nix-build -A hs-checks
- run: nix-build shell.nix
mingw:
runs-on: windows-latest
defaults:
run:
shell: C:\msys64\msys2_shell.cmd -mingw64 -defterm -no-start -here -c ". <(cygpath '{0}')"
working-directory: ./pkg/urbit
steps:
- uses: actions/checkout@v2
with:
lfs: true
# echo suppresses pacman prompt
- run: echo|./configure
env:
CACHIX_CACHE: ares
CACHIX_AUTH_TOKEN: ${{ secrets.CACHIX_AUTH_TOKEN }}
- run: make build/urbit build/urbit-worker
- run: build/urbit -l -d -B ../../bin/solid.pill -F bus && curl -f --data '{"source":{"dojo":"+hood/exit"},"sink":{"app":"hood"}}' http://localhost:12321

6
.gitignore vendored
View File

@ -55,7 +55,11 @@ release/
dist/
out/
work/
pkg/*/*.a
*.o
*.so
*.dll
*.dylib
# Landscape Dev
urbitrc
@ -78,3 +82,5 @@ pkg/interface/link-webext/web-ext-artifacts
# Logs
*.log
.vercel

View File

@ -1,3 +0,0 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-checkout.\n"; exit 2; }
git lfs post-checkout "$@"

View File

@ -1,3 +0,0 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-commit.\n"; exit 2; }
git lfs post-commit "$@"

View File

@ -1,3 +0,0 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/post-merge.\n"; exit 2; }
git lfs post-merge "$@"

View File

@ -1,3 +0,0 @@
#!/bin/sh
command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting .git/hooks/pre-push.\n"; exit 2; }
git lfs pre-push "$@"

11
.vercel/README.txt Normal file
View File

@ -0,0 +1,11 @@
> Why do I have a folder named ".vercel" in my project?
The ".vercel" folder is created when you link a directory to a Vercel project.
> What does the "project.json" file contain?
The "project.json" file contains:
- The ID of the Vercel project that you linked ("projectId")
- The ID of the user or team your Vercel project is owned by ("orgId")
> Should I commit the ".vercel" folder?
No, you should not share the ".vercel" folder with anyone.
Upon creation, it will be automatically added to your ".gitignore" file.

1
.vercel/project.json Normal file
View File

@ -0,0 +1 @@
{"orgId":"EDiU8DZExvM9N4unZGYQbG3d","projectId":"prj_fbAU5smemBgtr5t8lsk5ZoT9zNtI"}

16
.vercelignore Normal file
View File

@ -0,0 +1,16 @@
bin
doc
extras
nix
pkg/arvo
pkg/base-dev
pkg/docker-image
pkg/ent
pkg/garden
pkg/garden-dev
pkg/ge-additions
pkg/herb
pkg/hs
pkg/libaes_siv
pkg/urbit
sh

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e0af91e5c51359719aaa943f37a1e953989c786412616b18fbaa0addb2cf0740
size 10272514
oid sha256:9a56f675d2a6c5dafa92a9e2d55040d994f3d3d27a1ed827bd87d1158b1e69d0
size 3749183

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:23d8235b19a3404e0bfbed54aa56a018255beb1f33457e37f521bc0763b4d0eb
size 6245506
oid sha256:e6e3c7c0274352d2cfba2a9f2b3382cdeab0e0fb97455b42293a214561d177ee
size 1101949

3
bin/multi-brass.pill Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:049801d388b4cb7203854b4668826688c21089f90430bd547d276e7b59386e8d
size 5588170

3
bin/multi.pill Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c27cdb47bccda98ba68556181cae6cd845c6daf8d7426d82adf67c1e8f532be9
size 7454265

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:12ba08bb71205669907a99e722e1339b3777c2c189f49764b8bbfbeabc38f3d6
size 16596163
oid sha256:1f75add9e2b4522ee18a3ef64beb52a3f3b49345e8ac31e4954449c4f4d3b2ef
size 21338783

View File

@ -1,3 +1,4 @@
/* Examples
Shared urbit and urbit-worker binaries:
@ -85,19 +86,11 @@ let
# Local vendored packages defined in ./pkg.
# For non-vendored nixpkgs specific package overrides, see ./nix/overlays.
pkgsLocal = {
argon2u = callPackage ./nix/pkgs/argon2u { };
ca-bundle = callPackage ./nix/pkgs/ca-bundle { };
ed25519 = callPackage ./nix/pkgs/ed25519 { };
ent = callPackage ./nix/pkgs/ent { };
ge-additions = callPackage ./nix/pkgs/ge-additions { };
libaes_siv = callPackage ./nix/pkgs/libaes_siv { };
libscrypt = callPackage ./nix/pkgs/libscrypt { };
libaes_siv = callPackage ./nix/pkgs/libaes_siv { inherit (pkgsNative) cmake; };
murmur3 = callPackage ./nix/pkgs/murmur3 { };
@ -113,8 +106,12 @@ let
solid = callPackage ./nix/pkgs/pill/solid.nix { };
marsSources = callPackage ./nix/pkgs/marsSources { };
urbit = callPackage ./nix/pkgs/urbit { inherit enableStatic; };
urcrypt = callPackage ./nix/pkgs/urcrypt { inherit enableStatic; };
docker-image = callPackage ./nix/pkgs/docker-image { };
hs = callPackage ./nix/pkgs/hs {

View File

@ -2,7 +2,8 @@
"packages": [
"pkg/npm/*",
"pkg/btc-wallet",
"pkg/interface"
"pkg/interface",
"pkg/grid"
],
"version": "independent"
}

View File

@ -11,6 +11,11 @@ in {
outputs = [ "out" "dev" "lib" ];
});
secp256k1 = prev.secp256k1.overrideAttrs (_attrs: {
version = final.sources.secp256k1.rev;
src = final.sources.secp256k1;
});
libsigsegv = prev.libsigsegv.overrideAttrs (attrs: {
patches = optionalList attrs.patches ++ [
../pkgs/libsigsegv/disable-stackvma_fault-linux-arm.patch

View File

@ -1,30 +0,0 @@
{ stdenv, sources, enableParallelBuilding ? true }:
stdenv.mkDerivation {
pname = "argon2u";
version = sources.argon2u.rev;
src = sources.argon2u;
postPatch = ''
substituteInPlace Makefile --replace 'ar rcs' '$(AR) rcs'
'';
buildPhase = ''
make libargon2.a
'';
installPhase = ''
mkdir -p $out/{lib,include}
cp libargon2.a $out/lib/
cp include/argon2.h $out/include/
cp ./src/blake2/*.h $out/include/
'';
makeFlags = [
"AR=${stdenv.cc.targetPrefix}ar" # Fix cross-compilation
];
NO_THREADS = true;
inherit enableParallelBuilding;
}

View File

@ -1,46 +1,21 @@
{ lib, stdenvNoCC, bc }:
{ lib, stdenvNoCC, marsSources }:
stdenvNoCC.mkDerivation {
name = "arvo";
src = lib.cleanSource ../../../pkg/arvo;
buildInputs = [ bc ];
src = marsSources;
outputs = [ "out" "ropsten" ];
phases = [ "mainnetPhase" "ropstenPhase" ];
mainnetPhase = ''
cp -r $src/ $out
chmod -R u+w $out
'';
ln -s ${marsSources.out}/arvo $out
'';
ropstenPhase = ''
cp -r $src tmp
chmod -R u+w tmp
ZUSE=tmp/sys/zuse.hoon
AMES=tmp/sys/vane/ames.hoon
ACME=tmp/app/acme.hoon
# Replace the mainnet azimuth contract with the ropsten contract
sed --in-place \
's/\(\+\+ contracts \)mainnet\-contracts/\1ropsten-contracts/' \
$ZUSE
# Increment the %ames protocol version
sed -r --in-place \
's_^(=/ protocol\-version=\?\(.*\) %)([0-7])_echo "\1$(echo "(\2+1) % 8" | bc)"_e' \
$AMES
# Use the staging API in :acme
sed --in-place \
's_https://acme-v02.api.letsencrypt.org/directory_https://acme-staging-v02.api.letsencrypt.org/directory_' \
$ACME
cp -r tmp $ropsten
chmod -R u+w $ropsten
'';
ln -s ${marsSources.ropsten}/arvo $ropsten
'';
preferLocalBuild = true;
}

View File

@ -1,21 +0,0 @@
{ stdenv, sources }:
stdenv.mkDerivation {
pname = "ed25519";
version = sources.ed25519.rev;
src = sources.ed25519;
buildPhase = ''
CFLAGS="-O3 -Wall -I$src/src"
for f in $(find src -type f -name '*.c'); do
$CC $CFLAGS -c $f -o "''${f//\//_}.o"
done
'';
installPhase = ''
mkdir -p $out/{lib,include}
$AR rcs $out/lib/libed25519.a *.o
cp $src/src/*.h $out/include/
'';
}

View File

@ -1,13 +0,0 @@
{ lib, stdenv, ed25519, enableParallelBuilding ? true }:
stdenv.mkDerivation {
name = "ge-additions";
src = lib.cleanSource ../../../pkg/ge-additions;
buildInputs = [ ed25519 ];
installFlags = [ "PREFIX=$(out)" ];
inherit enableParallelBuilding;
}

View File

@ -0,0 +1,34 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,6 +5,8 @@ if("${CMAKE_BUILD_TYPE}" STREQUAL "")
set(CMAKE_BUILD_TYPE Release)
endif("${CMAKE_BUILD_TYPE}" STREQUAL "")
+option(BUILD_SHARED_LIBS "Build shared libraries" ON)
+
include(GNUInstallDirs)
# Warning: don't use the UB sanitizer in production builds. It can introduce timing side-channels
@@ -31,10 +33,12 @@ endif(NOT DISABLE_DOCS)
configure_file(config.h.in config.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
+if(BUILD_SHARED_LIBS)
add_library(aes_siv SHARED aes_siv.c)
target_include_directories(aes_siv PUBLIC ${OPENSSL_INCLUDE_DIR})
target_link_libraries(aes_siv ${OPENSSL_CRYPTO_LIBRARY})
set_target_properties(aes_siv PROPERTIES VERSION "1.0.1" SOVERSION 1)
+endif()
add_library(aes_siv_static STATIC aes_siv.c)
target_include_directories(aes_siv_static PUBLIC ${OPENSSL_INCLUDE_DIR})
@@ -63,7 +67,9 @@ endif(ENABLE_SANITIZER)
add_executable(bench EXCLUDE_FROM_ALL bench.c)
target_link_libraries(bench aes_siv_static)
+if(BUILD_SHARED_LIBS)
install(TARGETS aes_siv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
+endif()
install(TARGETS aes_siv_static ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(FILES aes_siv.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

View File

@ -1,12 +1,17 @@
{ lib, stdenv, openssl, enableParallelBuilding ? true }:
{ stdenv, sources, cmake, openssl, enableParallelBuilding ? true }:
stdenv.mkDerivation {
name = "libaes_siv";
src = lib.cleanSource ../../../pkg/libaes_siv;
version = sources.libaes_siv.rev;
src = sources.libaes_siv;
patches = [ ./cmakefiles_static.patch ];
nativeBuildInputs = [ cmake ];
buildInputs = [ openssl ];
installFlags = [ "PREFIX=$(out)" ];
cmakeFlags = [
"-DBUILD_SHARED_LIBS=OFF"
];
inherit enableParallelBuilding;
}

View File

@ -1,35 +0,0 @@
{ stdenv, sources }:
stdenv.mkDerivation {
pname = "libscrypt";
version = sources.libscrypt.rev;
src = sources.libscrypt;
buildPhase = ''
sources=" \
crypto_scrypt-check \
crypto_scrypt-hash \
crypto_scrypt-hexconvert \
crypto_scrypt-nosse \
crypto-mcf \
crypto-scrypt-saltgen \
slowequals \
sha256 \
b64 \
"
CFLAGS="-I$src -Wall -ffast-math -O3 -D_FORTIFY_SOURCE=2 -fstack-protector"
for s in $sources; do
$CC $CFLAGS -c $src/$s.c -o $s.o
done
$AR rcs libscrypt.a *.o
'';
installPhase = ''
mkdir -p $out/{lib,include}
cp libscrypt.a $out/lib
cp $src/*.h $out/include/
'';
}

View File

@ -0,0 +1,46 @@
{ lib, stdenvNoCC, bc }:
stdenvNoCC.mkDerivation {
name = "sources";
src = lib.cleanSource ../../../pkg;
buildInputs = [ bc ];
outputs = [ "out" "ropsten" ];
phases = [ "mainnetPhase" "ropstenPhase" ];
mainnetPhase = ''
cp -r $src $out
chmod -R u+w $out
'';
ropstenPhase = ''
cp -r $src tmp
chmod -R u+w tmp
ZUSE=tmp/arvo/sys/zuse.hoon
AMES=tmp/arvo/sys/vane/ames.hoon
ACME=tmp/arvo/app/acme.hoon
# Replace the mainnet azimuth contract with the ropsten contract
sed --in-place \
's/\(\+\+ contracts \)mainnet\-contracts/\1ropsten-contracts/' \
$ZUSE
# Increment the %ames protocol version
sed -r --in-place \
's_^(=/ protocol\-version=\?\(.*\) %)([0-7])_echo "\1$(echo "(\2+1) % 8" | bc)"_e' \
$AMES
# Use the staging API in :acme
sed --in-place \
's_https://acme-v02.api.letsencrypt.org/directory_https://acme-staging-v02.api.letsencrypt.org/directory_' \
$ACME
cp -r tmp $ropsten
chmod -R u+w $ropsten
'';
preferLocalBuild = true;
}

View File

@ -1,8 +1,12 @@
{ lib, stdenv, coreutils, pkgconfig, argon2u, cacert, ca-bundle, curlMinimal
, ed25519, ent, ge-additions, gmp, h2o, herb, ivory, libaes_siv, libscrypt
, libsigsegv, libuv, lmdb, murmur3, openssl, secp256k1, softfloat3, zlib
, enableStatic ? stdenv.hostPlatform.isStatic, enableDebug ? false
, doCheck ? true, enableParallelBuilding ? true, dontStrip ? true }:
{ lib, stdenv, coreutils, pkgconfig # build/env
, cacert, ca-bundle, ivory # codegen
, curlMinimal, ent, gmp, h2o, libsigsegv, libuv, lmdb # libs
, murmur3, openssl, softfloat3, urcrypt, zlib #
, enableStatic ? stdenv.hostPlatform.isStatic # opts
, enableDebug ? false
, doCheck ? true
, enableParallelBuilding ? true
, dontStrip ? true }:
let
@ -19,30 +23,23 @@ in stdenv.mkDerivation {
nativeBuildInputs = [ pkgconfig ];
buildInputs = [
argon2u
cacert
ca-bundle
curlMinimal
ed25519
ent
ge-additions
gmp
h2o
ivory.header
libaes_siv
libscrypt
libsigsegv
libuv
lmdb
murmur3
openssl
secp256k1
softfloat3
urcrypt
zlib
];
checkInputs = [ herb ];
# Ensure any `/usr/bin/env bash` shebang is patched.
postPatch = ''
patchShebangs ./configure
@ -56,9 +53,14 @@ in stdenv.mkDerivation {
cp ./build/urbit-worker $out/bin/urbit-worker
'';
dontDisableStatic = enableStatic;
configureFlags = if enableStatic
then [ "--disable-shared" "--enable-static" ]
else [];
CFLAGS = [ (if enableDebug then "-O0" else "-O3") "-g" ]
++ lib.optionals (!enableDebug) [ "-Werror" ]
++ lib.optionals enableStatic [ "-static" ];
++ lib.optionals (!enableDebug) [ "-Werror" ];
MEMORY_DEBUG = enableDebug;
CPU_DEBUG = enableDebug;

View File

@ -0,0 +1,21 @@
{ stdenv, autoreconfHook, pkgconfig
, libaes_siv, openssl, secp256k1
, enableStatic ? stdenv.hostPlatform.isStatic }:
stdenv.mkDerivation rec {
name = "urcrypt";
src = ../../../pkg/urcrypt;
# XX why are these required for darwin?
dontDisableStatic = enableStatic;
configureFlags = if enableStatic
then [ "--disable-shared" "--enable-static" ]
else [];
nativeBuildInputs =
[ autoreconfHook pkgconfig ];
propagatedBuildInputs =
[ openssl secp256k1 libaes_siv ];
}

65
nix/sources-pmnsh.json Normal file
View File

@ -0,0 +1,65 @@
{
"curl": {
"branch": "master",
"description": "A command line tool and library for transferring data with URL syntax",
"homepage": "http://curl.se/",
"pmnsh": {
"include": "include",
"lib": "lib/.libs",
"prepare": "autoreconf -vfi && ./configure --disable-shared --disable-ldap --disable-rtsp --without-brotli --without-libidn2 --without-libpsl --without-nghttp2 --with-openssl",
"make": "-C lib libcurl.la"
},
"owner": "curl",
"repo": "curl",
"rev": "curl-7_77_0",
"type": "tarball",
"url": "https://github.com/curl/curl/archive/curl-7_77_0.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"lmdb": {
"branch": "mdb.master",
"description": "LMDB library",
"homepage": "http://www.lmdb.tech/",
"pmnsh": {
"strip": 2,
"make": "liblmdb.a"
},
"owner": "LMDB",
"repo": "lmdb",
"rev": "48a7fed59a8aae623deff415dda27097198ca0c1",
"type": "tarball",
"url": "https://github.com/LMDB/lmdb/archive/48a7fed59a8aae623deff415dda27097198ca0c1.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"uv": {
"branch": "v1.x",
"description": "Cross-platform asynchronous I/O",
"homepage": "http://libuv.org/",
"pmnsh": {
"include": "include",
"lib": ".libs",
"prepare": "./autogen.sh && ./configure --disable-shared",
"make": "libuv.la",
"compat": {
"m1brew": false
}
},
"owner": "libuv",
"repo": "libuv",
"rev": "v1.40.0",
"type": "tarball",
"url": "https://github.com/libuv/libuv/archive/v1.40.0.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ent": {
"pmnsh": {
"prepare": "./configure"
}
},
"urcrypt": {
"pmnsh": {
"prepare": "./autogen.sh && ./configure --disable-shared PKG_CONFIG_PATH=../secp256k1 CFLAGS=\"-I../secp256k1/include -I../libaes_siv\" LDFLAGS=-L../libaes_siv",
"make": "install"
}
}
}

View File

@ -1,38 +1,24 @@
{
"argon2u": {
"branch": "master",
"description": "With argon2u. Based off https://github.com/P-H-C/phc-winner-argon2",
"homepage": "",
"owner": "urbit",
"repo": "argon2",
"rev": "4da94a611ee62bad87ab2b131ffda3bcc0723d9c",
"sha256": "0bqq1hg367l4jkb6cqhxlblpvdbwz3l586qsfakwzfd9wdvnm3yc",
"type": "tarball",
"url": "https://github.com/urbit/argon2/archive/4da94a611ee62bad87ab2b131ffda3bcc0723d9c.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"ed25519": {
"branch": "master",
"description": "Submodule included by Urbit",
"homepage": null,
"owner": "urbit",
"repo": "ed25519",
"rev": "76385f2ebbbc9580a9c236952d68d11d73a6135c",
"sha256": "0s1spif4s9lgcwcny3fl2fvpbw6acqn3s8r6qxnrmkd9icgyw4cp",
"type": "tarball",
"url": "https://github.com/urbit/ed25519/archive/76385f2ebbbc9580a9c236952d68d11d73a6135c.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"h2o": {
"branch": "master",
"description": "H2O - the optimized HTTP/1, HTTP/2, HTTP/3 server",
"homepage": "https://h2o.examp1e.net",
"pmnsh": {
"include": "include",
"prepare": "cmake .",
"make": "libh2o",
"compat": {
"mingw": {
"prepare": "cmake -G\"MSYS Makefiles\" -DCMAKE_INSTALL_PREFIX=. ."
}
}
},
"owner": "h2o",
"repo": "h2o",
"rev": "v2.2.4",
"sha256": "0176x0bzjry19zs074a9i5vhncc842xikmx43wj61jky318nq4w4",
"rev": "v2.2.6",
"sha256": "0qni676wqvxx0sl0pw9j0ph7zf2krrzqc1zwj73mgpdnsr8rsib7",
"type": "tarball",
"url": "https://github.com/h2o/h2o/archive/v2.2.4.tar.gz",
"url": "https://github.com/h2o/h2o/archive/v2.2.6.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"hackage.nix": {
@ -59,22 +45,37 @@
"url": "https://github.com/input-output-hk/haskell.nix/archive/bbb34dcdf7b90d478002f91713531f418ddf1b53.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"libscrypt": {
"libaes_siv": {
"branch": "master",
"description": null,
"homepage": null,
"owner": "urbit",
"repo": "libscrypt",
"rev": "029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2",
"sha256": "17pcxypzjmmrvacw45cacvibm6mlr9ip30hy30l1appsnywx679n",
"pmnsh": {
"compat": {
"m1brew": {
"prepare": "cmake .",
"make": "install CFLAGS=$(pkg-config --cflags openssl)"
},
"mingw": {
"prepare": "cmake -G\"MSYS Makefiles\" -DDISABLE_DOCS:BOOL=ON .",
"make": "aes_siv_static"
}
}
},
"owner":"dfoxfranke",
"repo": "libaes_siv",
"rev": "9681279cfaa6e6399bb7ca3afbbc27fc2e19df4b",
"sha256": "1g4wy0m5wpqx7z6nillppkh5zki9fkx9rdw149qcxh7mc5vlszzi",
"type": "tarball",
"url": "https://github.com/urbit/libscrypt/archive/029693ff1cbe4f69d3a2da87d0f4f034f92cc0c2.tar.gz",
"url": "https://github.com/dfoxfranke/libaes_siv/archive/9681279cfaa6e6399bb7ca3afbbc27fc2e19df4b.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"murmur3": {
"branch": "master",
"description": null,
"homepage": null,
"pmnsh": {
"make": "static"
},
"owner": "urbit",
"repo": "murmur3",
"rev": "71a75d57ca4e7ca0f7fc2fd84abd93595b0624ca",
@ -111,6 +112,19 @@
"branch": "master",
"description": null,
"homepage": null,
"pmnsh": {
"include": "source/include",
"compat": {
"m1brew": {
"lib": "build/template-FAST_INT64",
"make": "-C build/template-FAST_INT64 libsoftfloat3.a"
},
"mingw": {
"lib": "build/Win64-MinGW-w64",
"make": "-C build/Win64-MinGW-w64 libsoftfloat3.a"
}
}
},
"owner": "urbit",
"repo": "berkeley-softfloat-3",
"rev": "ec4c7e31b32e07aad80e52f65ff46ac6d6aad986",
@ -119,6 +133,24 @@
"url": "https://github.com/urbit/berkeley-softfloat-3/archive/ec4c7e31b32e07aad80e52f65ff46ac6d6aad986.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"secp256k1": {
"branch": "master",
"description": "Optimized C library for ECDSA signatures and secret/public key operations on curve secp256k1.",
"homepage": null,
"pmnsh": {
"include": "include",
"lib": ".libs",
"prepare": "./autogen.sh && ./configure --disable-shared --enable-module-recovery CFLAGS=-DSECP256K1_API=",
"make": "libsecp256k1.la"
},
"owner": "bitcoin-core",
"repo": "secp256k1",
"rev": "26de4dfeb1f1436dae1fcf17f57bdaa43540f940",
"sha256": "03i3nv8d3ci7q9y98q11rrp3rvwdqc0hc0ss0pr6xckybvizsmbb",
"type": "tarball",
"url": "https://github.com/bitcoin-core/secp256k1/archive/26de4dfeb1f1436dae1fcf17f57bdaa43540f940.tar.gz",
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
},
"stackage.nix": {
"branch": "master",
"description": "Automatically generated Nix expressions of Stackage snapshots",

BIN
package-lock.json generated

Binary file not shown.

View File

@ -5,17 +5,14 @@
"eslint": "^7.29.0",
"husky": "^6.0.0",
"lerna": "^4.0.0",
"lint-staged": "^11.0.0"
"lint-staged": "^11.1.2",
"prettier": "^2.3.2"
},
"scripts": {
"watch-libs": "lerna run watch --no-private --parallel",
"build-libs": "lerna run build --no-private",
"test": "lerna run test",
"prepare": "husky install .husky",
"bootstrap": "lerna bootstrap",
"build:prod": "lerna run build:prod"
},
"lint-staged": {
"*.{js,ts,tsx}": "eslint --cache --fix"
}
}

View File

@ -22,6 +22,7 @@
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
bec byk.bowl(r da+now.bowl)
::
++ on-init on-init:def
++ on-save !>(state)
@ -86,6 +87,7 @@
--
::
|_ =bowl:gall
++ bec byk.bowl(r da+now.bowl)
::
++ poke-spider
|= [=path our=@p =cage]
@ -108,7 +110,7 @@
=/ new-tid=@ta
:((cury cat 3) dap.bowl '--' (scot %uv eny.bowl))
=/ args
[~ `new-tid %claz-prep-command !>([node-url command])]
[~ `new-tid bec %claz-prep-command !>([node-url command])]
:~ (watch-spider /prepare our.bowl /thread-result/[new-tid])
(poke-spider /prepare our.bowl %spider-start !>(args))
==

View File

@ -132,6 +132,12 @@
=? site ?=([%'~debug' *] site) t.site
?~ ext
$(ext `%html, site [%index ~]) ::NOTE hack
:: serve dynamic session.js
::
?: =([/js/session `%js] [site ext])
%- js-response:gen
%- as-octt:mimes:html
"window.ship = '{(slag 1 (scow %p our.bowl))}';"
:: if not json, serve static file
::
?. ?=([~ %json] ext)
@ -418,13 +424,16 @@
++ apps
|%
++ all
^- (list term)
%+ murn
(scry (list path) %ct %home /app)
|= =path
^- (unit term)
?. ?=([%app @ %hoon ~] path) ~
`i.t.path
^- (list dude:gall)
%- zing
^- (list (list dude:gall))
%+ turn
~(tap in (scry (set desk) %cd %$ /))
|= =desk
^- (list dude:gall)
=- (turn ~(tap in -) head)
;; (set [dude:gall ?]) ::TODO for some reason we need this?
(scry (set [dude:gall ?]) %ge desk /)
::
++ running
|= app=term

View File

@ -12,8 +12,8 @@
<body class="w-100 h-100">
<div id="root" class="w-100 h-100">
</div>
<script src="/~landscape/js/channel.js"></script>
<script src="/~landscape/js/session.js"></script>
<script src="/~debug/js/channel.js"></script>
<script src="/~debug/js/session.js"></script>
<script src="/~debug/js/index.js"></script>
</body>

View File

@ -12,7 +12,7 @@
=> |% :: external structures
+$ id @tasession :: session id
+$ house :: all state
$: %6
$: %8
egg=@u :: command count
hoc=(map id session) :: conversations
acl=(set ship) :: remote access whitelist
@ -65,8 +65,8 @@
$~ [%ex *hoon]
$% [%ur p=@t] :: http GET request
[%ge p=dojo-model] :: generator
[%te p=term q=(list dojo-source)] :: thread
[%dv p=path] :: core from source
[%te p=[=desk =term] q=(list dojo-source)] :: thread
[%dv p=beak q=path] :: core from source
[%ex p=hoon] :: hoon expression
[%sa p=mark] :: example mark value
[%as p=mark q=dojo-source] :: simple transmute
@ -79,7 +79,7 @@
== ::
+$ dojo-server :: numbered device
$: p=@ud :: assembly index
q=path :: gate path
q=[=desk =path] :: gate location
== ::
+$ dojo-config :: configuration
$: p=(list dojo-source) :: by order
@ -125,7 +125,14 @@
++ to-command
|= [gol=goal mod=dojo-model]
^- dojo-command
[[%poke gol] [0 [%ge mod(q.p [q.gol q.p.mod])]]]
=/ =desk
::TODO maybe should recognize if the user specified a desk explicitly.
:: currently eats the :app|desk#gen case.
=+ gop=(en-beam dir(q q.gol, s /))
?. .^(? %gu gop)
q.dir
.^(desk %gd gop)
[[%poke gol] [0 [%ge mod(q.p [desk q.gol path.q.p.mod])]]]
::
++ parse-variable
|* [sym=rule src=rule]
@ -217,7 +224,7 @@
;~ pose
;~(plug (cold %ur lus) parse-url)
;~(plug (cold %ge lus) parse-model)
;~(plug (cold %te hep) sym (star ;~(pfix ace parse-source)))
;~(plug (cold %te hep) parse-thread (star ;~(pfix ace parse-source)))
;~(plug (cold %as pam) sym ;~(pfix ace parse-source))
;~(plug (cold %do cab) parse-hoon ;~(pfix ace parse-source))
parse-value
@ -263,7 +270,20 @@
auri:de-purl:html
::
++ parse-model ;~(plug parse-server parse-config)
++ parse-server (stag 0 (most fas sym))
::
++ parse-server
%+ stag 0
;~ plug
;~(pose ;~(sfix sym zap) (easy q.dir))
(most fas sym)
==
::
++ parse-thread
;~ plug
;~(pose ;~(sfix sym zap) (easy q.dir))
sym
==
::
++ parse-hoon tall:hoon-parser
::
++ parse-rood
@ -334,11 +354,11 @@
:: +dy-sing: make a clay read request
::
++ dy-sing
|= [way=wire =care:clay =path]
|= [way=wire =care:clay =beak =path]
^+ +>+>
?> ?=(~ pux)
%- he-card(poy `+>+<(pux `way))
=/ [=ship =desk =case:clay] he-beak
=/ [=ship =desk =case:clay] beak
[%pass way %arvo %c %warp ship desk ~ %sing care case path]
::
++ dy-request
@ -427,7 +447,13 @@
++ dy-init-server :: ++dojo-server
|= srv=dojo-server
=. p.srv num
[srv +>.$(num +(num), job (~(put by job) num [%dv [%gen q.srv]]))]
=/ bek=beak he-beak
:- srv
%_ +>.$
num +(num)
job %+ ~(put by job) num
[%dv bek(q desk.q.srv) [%gen path.q.srv]]
==
::
++ dy-init-config :: prepare config
|= cig=dojo-config
@ -512,7 +538,7 @@
$?(%eny %now %our) !!
%lib .(lib ~)
%sur .(sur ~)
%dir .(dir [[our.hid %home ud+0] /])
%dir .(dir [[our.hid %base ud+0] /])
==
=+ cay=(~(got by rez) p.q.mad)
?- -.p.mad
@ -538,8 +564,8 @@
::
%dir =+ ^= pax ^- path
=+ pax=((dy-cast path !>(*path)) q.cay)
?: ?=(~ pax) ~[(scot %p our.hid) %home '0']
?: ?=([@ ~] pax) ~[i.pax %home '0']
?: ?=(~ pax) ~[(scot %p our.hid) %base '0']
?: ?=([@ ~] pax) ~[i.pax %base '0']
?: ?=([@ @ ~] pax) ~[i.pax i.t.pax '0']
pax
=. dir (need (de-beam pax))
@ -673,9 +699,9 @@
[%sa mark]
[%as mark dy-shown]
[%do hoon dy-shown]
[%te term (list dy-shown)]
[%ge path (list dy-shown) (map term (unit dy-shown))]
[%dv path]
[%te [desk term] (list dy-shown)]
[%ge [desk path] (list dy-shown) (map term (unit dy-shown))]
[%dv beak path]
==
==
::
@ -850,7 +876,7 @@
(dy-hand %noun q.cag)
::
++ dy-wool-poke
|= [fil=term src=(list dojo-source)]
|= [[=desk =term] src=(list dojo-source)]
^+ +>+>
?> ?=(~ pux)
=/ tid (scot %ta (cat 3 'dojo_' (scot %uv (sham eny.hid))))
@ -860,7 +886,9 @@
[%pass /wool %agent [our.hid %spider] %watch /thread-result/[tid]]
%- he-card
=/ =cage :: also sub
[%spider-start !>([~ `tid fil (dy-some src)])]
::TODO would be nice if spider supported starting from paths,
:: for semantics/abilities/code closer to generators.
[%spider-start !>([~ `tid he-beak(q.dir desk) term (dy-some src)])]
[%pass /wool %agent [our.hid %spider] %poke cage]
::
++ dy-make :: build step
@ -871,7 +899,7 @@
%ur (dy-request /hand `request:http`[%'GET' p.bil ~ ~])
%te (dy-wool-poke p.bil q.bil)
%ex (dy-mere p.bil)
%dv (dy-sing hand+p.bil %a (snoc p.bil %hoon))
%dv (dy-sing hand+q.bil %a p.bil (snoc q.bil %hoon))
%ge (dy-run-generator (dy-cage p.p.p.bil) q.p.bil)
%sa
=+ .^(=dais:clay cb+(en-beam he-beak /[p.bil]))
@ -879,6 +907,9 @@
::
%as
=/ cag=cage (dy-cage p.q.bil)
=/ has-mark .?((get-fit:clay he-beak %mar p.bil))
?. has-mark :: yolo
(dy-hand p.bil q.cag)
=+ .^(=tube:clay cc+(en-beam he-beak /[p.cag]/[p.bil]))
(dy-hand p.bil (tube q.cag))
::
@ -1015,13 +1046,13 @@
::
++ he-prow :: where we are
^- tape
?: &(=(our.hid p.dir) =(%home q.dir) =([%ud 0] r.dir) =(~ s.dir)) ~
?: &(=(our.hid p.dir) =(%base q.dir) =([%ud 0] r.dir) =(~ s.dir)) ~
%+ weld
?: &(=(our.hid p.dir) =([%ud 0] r.dir))
(weld "/" (trip q.dir))
;: weld
"/" ?:(=(our.hid p.dir) "=" (scow %p p.dir))
"/" ?:(=(%home q.dir) "=" (trip q.dir))
"/" ?:(=(%base q.dir) "=" (trip q.dir))
"/" ?:(=([%ud 0] r.dir) "=" (scow r.dir))
==
?:(=(~ s.dir) "" (spud s.dir))
@ -1039,6 +1070,7 @@
?+ way !!
[%hand *]
?~ riot
~> %slog.0^leaf/"dojo: %writ fail {<way>}"
(he-diff(poy ~) %tan >%generator-build-fail< >(snoc t.way %hoon)< ~)
(~(dy-hand dy u.poy(pux ~)) noun+!<(vase q.r.u.riot))
==
@ -1140,7 +1172,7 @@
:+ %clhp
[%rock %tas %cx]
%+ rash pax.source.com
rood:(vang | /(scot %p our.hid)/home/(scot %da now.hid))
rood:(vang | /(scot %p our.hid)/base/(scot %da now.hid))
::
%url [%ur (crip (en-purl:html url.source.com))]
%api !!
@ -1171,7 +1203,7 @@
%hoon
:* %do
%+ rash code.source.com
tall:(vang | /(scot %p our.hid)/home/(scot %da now.hid))
tall:(vang | /(scot %p our.hid)/base/(scot %da now.hid))
$(num +(num), source.com next.source.com)
==
::
@ -1351,7 +1383,7 @@
++ complete-naked-poke
|= app=term
=/ pax=path
/(scot %p our.hid)/[q.byk.hid]/(scot %da now.hid)/app
/(scot %p our.hid)/[q:he-beam]/(scot %da now.hid)/app
%+ complete (cat 3 ':' app)
%+ murn ~(tap by dir:.^(arch %cy pax))
|= [=term ~]
@ -1381,7 +1413,7 @@
(cat 3 '|' gen)
:((cury cat 3) ':' app '|' gen)
=/ pfix=path
/(scot %p our.hid)/[q.byk.hid]/(scot %da now.hid)/gen/[app]
/(scot %p our.hid)/[q:he-beam]/(scot %da now.hid)/gen/[app]
::
%^ tab-generators:auto pfix `app
%+ murn
@ -1397,7 +1429,7 @@
|= gen=term
%+ complete (cat 3 '+' gen)
=/ pax=path
/(scot %p our.hid)/[q.byk.hid]/(scot %da now.hid)/gen
/(scot %p our.hid)/[q:he-beam]/(scot %da now.hid)/gen
%^ tab-generators:auto pax ~
%+ murn
~(tap by dir:.^(arch %cy pax))
@ -1493,12 +1525,53 @@
!>(state)
::
++ on-load
|= old=vase
?: ?=(%6 +<.old)
`..on-init(state !<(house old))
=/ old-5 !<([%5 egg=@u hoc=(map id session)] old)
=/ =house [%6 egg.old-5 hoc.old-5 *(set ship)]
`..on-init(state house)
|= ole=vase
|^ =+ old=!<(house-any ole)
=? old ?=(%5 -.old)
(house-5-to-6 old)
=? old ?=(?(%6 %7) -.old)
(house-6-7-to-8 +.old)
?> ?=(%8 -.old)
`..on-init(state old)
::
+$ house-any $%(house house-7 house-6 house-5)
::
+$ house-7 [%7 house-6-7]
+$ house-6 [%6 house-6-7]
+$ house-6-7
$: egg=@u :: command count
hoc=(map id session-6) :: conversations
acl=(set ship) :: remote access whitelist
== ::
+$ session-6 :: per conversation
$: say=sole-share :: command-line state
dir=beam :: active path
poy=(unit *) :: working
$: :: sur: structure imports
::
sur=(list cable:clay)
:: lib: library imports
::
lib=(list cable:clay)
==
var=(map term cage) :: variable state
old=(set term) :: used TLVs
buf=tape :: multiline buffer
== ::
++ house-6-7-to-8
|= old=house-6-7
[%8 egg.old (~(run by hoc.old) session-6-to-8) acl.old]
++ session-6-to-8
|= old=session-6
~? ?=(^ poy.old) [dap.hid %cancelling-for-load]
old(poy ~, -.dir [our.hid %base ud+0])
::
+$ house-5
[%5 egg=@u hoc=(map id session)]
++ house-5-to-6
|= old=house-5
[%6 egg.old hoc.old *(set ship)]
--
::
++ on-poke
|= [=mark =vase]
@ -1555,7 +1628,7 @@
=? hoc (~(has by hoc) id)
~& [%dojo-peer-replaced id]
(~(del by hoc) id)
=/ =session %*(. *session -.dir [our.hid %home ud+0])
=/ =session %*(. *session -.dir [our.hid %base ud+0])
=^ moves state
he-abet:~(he-prom he hid id ~ session)
[moves ..on-init]

View File

@ -49,6 +49,7 @@
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
bec byk.bowl(r da+now.bowl)
::
++ on-init on-init:def
++ on-save !>(state)
@ -117,6 +118,7 @@
--
::
|_ =bowl:gall
++ bec byk.bowl(r da+now.bowl)
++ poke-spider
|= [=path our=@p =cage]
^- card
@ -137,9 +139,7 @@
^- (list card)
=/ tid=@ta
:((cury cat 3) dap.bowl '--' node-id '--' (scot %uv eny.bowl))
=/ args
:^ ~ `tid %eth-send-txs
!>([node step txs])
=/ args [~ `tid bec %eth-send-txs !>([node step txs])]
:~ (watch-spider /send/[tid] our.bowl /thread-result/[tid])
(poke-spider /send/[tid] our.bowl %spider-start !>(args))
==
@ -151,7 +151,7 @@
.^ (list cord)
%cx
(scot %p our.bowl)
%home
%base
(scot %da now.bowl)
path
==

View File

@ -64,6 +64,7 @@
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
bec byk.bowl(r da+now.bowl)
::
++ on-init
^- (quip card _this)
@ -535,8 +536,9 @@
(cat 3 'eth-watcher--' (scot %uv eny.bowl))
:_ dog(running `[now.bowl new-tid])
=/ args
:^ ~ `new-tid %eth-watcher
!>([~ `watchpup`[- number pending-logs blocks]:dog])
:* ~ `new-tid bec %eth-watcher
!>([~ `watchpup`[- number pending-logs blocks]:dog])
==
:~ (watch-spider path our.bowl /thread-result/[new-tid])
(poke-spider path our.bowl %spider-start !>(args))
==

View File

@ -62,6 +62,7 @@
+* this .
do ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
bec byk.bowl(r da+now.bowl)
::
++ on-init
^- (quip card _this)
@ -174,6 +175,7 @@
--
::
|_ =bowl:gall
++ bec byk.bowl(r da+now.bowl)
++ setup-cards
^- (list card)
:~ wait-export
@ -297,7 +299,7 @@
::
%+ poke-spider /timestamps/[tid]
:- %spider-start
=- !>([~ `tid %eth-get-timestamps -])
=- !>([~ `tid bec %eth-get-timestamps -])
!> ^- [@t (list @ud)]
:- node-url
=- ~(tap in -)

View File

@ -1,46 +0,0 @@
/+ default-agent, verb
%+ verb |
^- agent:gall
=>
|%
++ goad
|= force=?
:~ [%pass /gall %arvo %g %goad force ~]
==
+$ state
$@ ~
[%0 ~]
--
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
::
++ on-poke
|= [=mark =vase]
?: ?=([%noun * %go] +<)
[(goad |) this]
?: ?=([%noun * %force] +<)
[(goad &) this]
(on-poke:def mark vase)
::
++ on-arvo
|= [wir=wire sin=sign-arvo]
?+ wir (on-arvo:def wir sin)
[%clay ~] `this
[%behn ~] `this :: backcompat
==
::
++ on-agent on-agent:def
++ on-fail on-fail:def
++ on-init on-init:def
++ on-leave on-leave:def
++ on-load
|= =vase
=+ !<(old=state vase)
?^ old `this
[(goad &) this]
::
++ on-peek on-peek:def
++ on-save !>([%0 ~])
++ on-watch on-watch:def
--

View File

@ -1,453 +0,0 @@
:: hark-graph-hook: notifications for graph-store [landscape]
::
/- post, group-store, metadata=metadata-store, hook=hark-graph-hook, store=hark-store
/+ resource, mdl=metadata, default-agent, dbug, graph-store, graph, grouplib=group, store=hark-store
::
::
~% %hark-graph-hook-top ..part ~
|%
+$ card card:agent:gall
+$ versioned-state
$% state-0
state-1
==
::
+$ state-0
[%0 base-state-0]
::
+$ state-1
[%1 base-state-0]
::
+$ base-state-0
$: watching=(set [resource index:post])
mentions=_&
watch-on-self=_&
==
::
++ scry
|* [[our=@p now=@da] =mold p=path]
?> ?=(^ p)
?> ?=(^ t.p)
.^(mold i.p (scot %p our) i.t.p (scot %da now) t.t.p)
::
++ scry-notif-conversion
|= [[our=@p now=@da] desk=term =mark]
^- $-(indexed-post:graph-store (unit notif-kind:hook))
%^ scry [our now]
$-(indexed-post:graph-store (unit notif-kind:hook))
/cf/[desk]/[mark]/notification-kind
--
::
=| state-1
=* state -
::
=<
%- agent:dbug
^- agent:gall
~% %hark-graph-hook-agent ..card ~
|_ =bowl:gall
+* this .
ha ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
met ~(. mdl bowl)
grp ~(. grouplib bowl)
gra ~(. graph bowl)
::
++ on-init
:_ this
~[watch-graph:ha]
::
++ on-save !>(state)
++ on-load
|= =vase
^- (quip card _this)
=+ !<(old=versioned-state vase)
=| cards=(list card)
|-
?: ?=(%0 -.old)
%_ $
-.old %1
::
cards
:_ cards
[%pass / %agent [our dap]:bowl %poke noun+!>(%rewatch-dms)]
==
:_ this(state old)
=. cards (flop cards)
?: (~(has by wex.bowl) [/graph our.bowl %graph-store])
cards
[watch-graph:ha cards]
::
++ on-watch
|= =path
^- (quip card _this)
=^ cards state
?+ path (on-watch:def path)
::
[%updates ~]
:_ state
%+ give:ha ~
:* %initial
watching
mentions
watch-on-self
==
==
[cards this]
::
++ on-poke
~/ %hark-graph-hook-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
%hark-graph-hook-action
(hark-graph-hook-action !<(action:hook vase))
%noun
(poke-noun !<(* vase))
==
[cards this]
::
++ poke-noun
|= non=*
[~ state]
:: ?> ?=(%rewatch-dms non)
:: =/ graphs=(list resource)
:: ~(tap in get-keys:gra)
:: %_ state
:: watching
:: %- ~(gas in watching)
:: (murn graphs |=(rid=resource ?:((should-watch:ha rid) `[rid ~] ~)))
:: ==
::
++ hark-graph-hook-action
|= =action:hook
^- (quip card _state)
|^
:- (give:ha ~[/updates] action)
?- -.action
%listen (listen +.action)
%ignore (ignore +.action)
%set-mentions (set-mentions +.action)
%set-watch-on-self (set-watch-on-self +.action)
==
++ listen
|= [graph=resource =index:post]
^+ state
state(watching (~(put in watching) [graph index]))
::
++ ignore
|= [graph=resource =index:post]
^+ state
state(watching (~(del in watching) [graph index]))
::
++ set-mentions
|= ment=?
^+ state
state(mentions ment)
::
++ set-watch-on-self
|= self=?
^+ state
state(watch-on-self self)
--
--
::
++ on-agent
~/ %hark-graph-hook-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
|^
?+ -.sign (on-agent:def wire sign)
%kick
:_ this
?. ?=([%graph ~] wire)
~
~[watch-graph:ha]
::
%fact
?. ?=(%graph-update-2 p.cage.sign)
(on-agent:def wire sign)
=^ cards state
(graph-update !<(update:graph-store q.cage.sign))
[cards this]
==
::
++ graph-update
|= =update:graph-store
^- (quip card _state)
?+ -.q.update `state
%add-graph (add-graph resource.q.update)
::
?(%remove-graph %archive-graph)
(remove-graph resource.q.update)
::
%remove-posts
(remove-posts resource.q.update indices.q.update)
::
%add-nodes
=* rid resource.q.update
=/ assoc=(unit association:metadata)
(peek-association:met %graph rid)
(check-nodes ~(val by nodes.q.update) rid assoc)
==
:: this is awful, but notification kind should always switch
:: on the index, so hopefully doesn't matter
:: TODO: rethink this
++ remove-posts
|= [rid=resource indices=(set index:graph-store)]
=/ to-remove
%- ~(gas by *(set [resource index:graph-store]))
(turn ~(tap in indices) (lead rid))
:_ state(watching (~(dif in watching) to-remove))
=/ convert (get-conversion:ha rid)
%+ roll
~(tap in indices)
|= [=index:graph-store out=(list card)]
=| =indexed-post:graph-store
=. index.p.indexed-post index
=/ notif-kind=(unit notif-kind:hook)
(convert indexed-post)
?~ notif-kind out
=/ =stats-index:store
[%graph rid (scag parent.index-len.u.notif-kind index)]
?. ?=(%each mode.u.notif-kind) out
:_ out
(poke-hark %read-each stats-index index)
::
++ poke-hark
|= =action:store
^- card
[%pass / %agent [our.bowl %hark-store] %poke hark-action+!>(action)]
::
++ remove-graph
|= rid=resource
=/ unwatched
%- ~(gas in *(set [resource index:graph-store]))
%+ skim ~(tap in watching)
|= [r=resource idx=index:graph-store]
=(r rid)
:_ state(watching (~(dif in watching) unwatched))
^- (list card)
:- (poke-hark:ha %remove-graph rid)
%- zing
%+ turn ~(tap in unwatched)
|= [r=resource =index:graph-store]
(give:ha ~[/updates] %ignore r index)
::
++ add-graph
|= rid=resource
^- (quip card _state)
=/ graph=graph:graph-store :: graph in subscription is bunted
(get-graph-mop:gra rid)
=/ node=(unit node:graph-store)
(bind (pry:orm:graph-store graph) |=([@ =node:graph-store] node))
=/ assoc=(unit association:metadata)
(peek-association:met %graph rid)
=^ cards state
(check-nodes (drop node) rid assoc)
?. (should-watch:ha rid assoc)
[cards state]
:_ state(watching (~(put in watching) [rid ~]))
(weld cards (give:ha ~[/updates] %listen [rid ~]))
::
++ check-nodes
|= $: nodes=(list node:graph-store)
rid=resource
assoc=(unit association:metadata)
==
abet:check:(abed:handle-update:ha rid nodes)
--
::
++ on-peek on-peek:def
::
++ on-leave on-leave:def
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?+ wire (on-arvo:def wire sign-arvo)
::
:: no longer necessary
[%validator @ ~] [~ this]
==
++ on-fail on-fail:def
--
::
|_ =bowl:gall
+* met ~(. mdl bowl)
grp ~(. grouplib bowl)
gra ~(. graph bowl)
::
++ get-conversion
|= rid=resource
^- $-(indexed-post:graph-store (unit notif-kind:hook))
=+ %^ scry [our now]:bowl
,mark=(unit mark)
/gx/graph-store/graph/(scot %p entity.rid)/[name.rid]/mark/noun
?~ mark
|=(=indexed-post:graph-store ~)
(scry-notif-conversion [our now]:bowl q.byk.bowl u.mark)
::
++ give
|= [paths=(list path) =update:hook]
^- (list card)
[%give %fact paths hark-graph-hook-update+!>(update)]~
::
++ watch-graph
^- card
[%pass /graph %agent [our.bowl %graph-store] %watch /updates]
::
++ poke-hark
|= =action:store
^- card
=- [%pass / %agent [our.bowl %hark-store] %poke -]
hark-action+!>(action)
::
++ is-mention
|= contents=(list content:post)
^- ?
?. mentions %.n
?~ contents %.n
?. ?=(%mention -.i.contents)
$(contents t.contents)
?: =(our.bowl ship.i.contents)
%.y
$(contents t.contents)
::
++ should-watch
|= [rid=resource assoc=(unit association:metadata)]
^- ?
?~ assoc
%.y
&(watch-on-self =(our.bowl entity.rid))
::
++ handle-update
|_ $: rid=resource :: input
updates=(list node:graph-store)
mark=(unit mark)
hark-pokes=(list action:store) :: output
new-watches=(list index:graph-store)
==
++ update-core .
::
++ abed
|= [r=resource upds=(list node:graph-store)]
=/ m=(unit ^mark)
(get-mark:gra r)
update-core(rid r, updates upds, mark m)
::
++ get-conversion
~+ (^get-conversion rid)
::
++ abet
^- (quip card _state)
:_ state(watching (~(uni in watching) (silt (turn new-watches (lead rid)))))
^- (list card)
%+ welp (turn (flop hark-pokes) poke-hark)
%- zing
%+ turn (flop new-watches)
|=(=index:graph-store (give ~[/updates] [%listen rid index]))
::
++ hark
|= =action:store
^+ update-core
update-core(hark-pokes [action hark-pokes])
::
++ new-watch
|= [=index:graph-store =watch-for:hook =index-len:hook]
=? new-watches =(%siblings watch-for)
[(scag parent.index-len index) new-watches]
=? new-watches =(%children watch-for)
[(scag self.index-len index) new-watches]
update-core
::
++ check
|- ^+ update-core
?~ updates
update-core
=/ core=_update-core
(check-node i.updates)
=. updates.core t.updates
$(update-core core)
::
++ check-node-children
|= =node:graph-store
^+ update-core
?: ?=(%empty -.children.node)
update-core
=/ children=(list [=atom =node:graph-store])
(tap:orm:graph-store p.children.node)
|- ^+ update-core
?~ children
update-core
=. update-core (check-node node.i.children)
$(children t.children)
::
++ check-node
|= =node:graph-store
^+ update-core
=. update-core (check-node-children node)
?: ?=(%| -.post.node)
update-core
=* pos p.post.node
=/ notif-kind=(unit notif-kind:hook)
(get-conversion [0 pos])
?~ notif-kind
update-core
=/ desc=@t
?: (is-mention contents.pos)
%mention
name.u.notif-kind
=* not-kind u.notif-kind
=/ parent=index:post
(scag parent.index-len.not-kind index.pos)
=/ notif-index=index:store
[%graph rid mark desc parent]
?: =(our.bowl author.pos)
(self-post node notif-index not-kind)
=. update-core
(update-unread-count not-kind notif-index [time-sent index]:pos)
=? update-core
?| =(desc %mention)
(~(has in watching) [rid parent])
=(mark `%graph-validator-dm)
==
=/ =contents:store
[%graph (limo pos ~)]
(add-unread notif-index [time-sent.pos %.n contents])
update-core
::
++ update-unread-count
|= [=notif-kind:hook =index:store time=@da ref=index:graph-store]
=/ =stats-index:store
(to-stats-index:store index)
?- mode.notif-kind
%count (hark %unread-count stats-index time)
%each (hark %unread-each stats-index ref time)
%none update-core
==
::
++ self-post
|= $: =node:graph-store
=index:store
=notif-kind:hook
==
^+ update-core
?> ?=(%& -.post.node)
=/ =stats-index:store
(to-stats-index:store index)
=. update-core
(hark %seen-index time-sent.p.post.node stats-index)
=? update-core ?=(%count mode.notif-kind)
(hark %read-count stats-index)
=? update-core watch-on-self
(new-watch index.p.post.node [watch-for index-len]:notif-kind)
update-core
::
++ add-unread
|= [=index:store =notification:store]
(hark %add-note index notification)
--
--

View File

@ -1,745 +0,0 @@
:: hark-store: notifications and unread counts [landscape]
::
:: hark-store can store unread counts differently, depending on the
:: resource.
:: - last seen. This way, hark-store simply stores an index into
:: graph-store, which represents the last "seen" item, useful for
:: high-volume applications which are intrinsically time-ordered. i.e.
:: chats, comments
:: - each. Hark-store will store an index for each item that is unread.
:: Usefull for non-linear, low-volume applications, i.e. blogs,
:: collections
::
/- post, group-store, metadata-store, store=hark-store
/+ resource, metadata, default-agent, dbug, graph-store, graphl=graph, verb, store=hark-store
::
::
~% %hark-store-top ..part ~
|%
+$ card card:agent:gall
+$ versioned-state
$% state:state-zero:store
state:state-one:store
state-2
state-3
state-4
state-5
state-6
state-7
==
+$ unread-stats
[indices=(set index:graph-store) last=@da]
::
+$ base-state
$: unreads-each=(jug stats-index:store index:graph-store)
unreads-count=(map stats-index:store @ud)
timeboxes=(map stats-index:store @da)
unread-notes=timebox:store
last-seen=(map stats-index:store @da)
=notifications:store
archive=notifications:store
current-timebox=@da
dnd=_|
==
::
+$ state-2
[%2 state-two:store]
::
+$ state-3
[%3 state-two:store]
::
+$ state-4
[%4 state-three:store]
::
+$ state-5
[%5 state-three:store]
::
+$ state-6
[%6 state-four:store]
::
+$ state-7
[%7 base-state]
::
::
++ orm ((ordered-map @da timebox:store) gth)
--
::
=| state-7
=* state -
::
=<
%+ verb |
%- agent:dbug
^- agent:gall
~% %hark-store-agent ..card ~
|_ =bowl:gall
+* this .
ha ~(. +> bowl)
def ~(. (default-agent this %|) bowl)
met ~(. metadata bowl)
gra ~(. graphl bowl)
::
++ on-init
:_ this
~[autoseen-timer]
::
++ on-save !>(state)
++ on-load
|= =old=vase
^- (quip card _this)
=/ old
!<(versioned-state old-vase)
=| cards=(list card)
|^
^- (quip card _this)
?- -.old
%7
:- (flop cards)
this(state old)
::
%6
%_ $
-.old %7
::
+.old
%* . *base-state
notifications (notifications:to-five:upgrade:store notifications.old)
archive ~
unreads-each unreads-each.old
unreads-count unreads-count.old
last-seen last-seen.old
current-timebox current-timebox
dnd dnd.old
==
==
::
%5
%_ $
-.old %6
notifications.old (notifications:to-four:upgrade:store notifications.old)
archive.old *notifications:state-four:store
==
::
%4
%_ $
-.old %5
::
last-seen.old
%- ~(run by last-seen.old)
|=(old=@da (min old now.bowl))
==
::
%3
%_ $
-.old %4
notifications.old (notifications:to-three:upgrade:store notifications.old)
archive.old *notifications:state-three:store
==
::
%2
%_ $
-.old %3
::
cards
:_ cards
[%pass / %agent [our dap]:bowl %poke noun+!>(%fix-dangling)]
==
::
%1
%_ $
::
old
%* . *state-2
unreads-each ((convert-unread ,(set index:graph-store)) uni-by unreads-each.old)
unreads-count ((convert-unread ,@ud) add unreads-count.old)
last-seen ((convert-unread ,@da) max last-seen.old)
notifications notifications.old
archive archive.old
current-timebox current-timebox.old
dnd dnd.old
==
==
::
%0
%_ $
::
old
%* . *state:state-one:store
notifications (convert-notifications-1 notifications.old)
archive (convert-notifications-1 archive.old)
current-timebox current-timebox.old
dnd dnd.old
==
==
==
::
++ uni-by
|= [a=(set index:graph-store) b=(set index:graph-store)]
=/ merged
(~(uni in a) b)
%- ~(gas in *(set index:graph-store))
%+ skip ~(tap in merged)
|=(=index:graph-store &(=((lent index) 3) !=(-:(flop index) 1)))
::
++ convert-unread
|* value=mold
|= [combine=$-([value value] value) unreads=(map index:store value)]
^- (map stats-index:store value)
%+ roll
~(tap in unreads)
|= [[=index:store val=value] out=(map stats-index:store value)]
=/ old=value
(~(gut by unreads) index (combine))
=/ =stats-index:store
(to-stats-index:store index)
(~(put by out) stats-index (combine old val))
::
++ convert-notifications-1
|= old=notifications:state-zero:store
%+ gas:orm:state-two:store *notifications:state-two:store
^- (list [@da timebox:state-two:store])
%+ murn
(tap:orm:state-zero:store old)
|= [time=@da =timebox:state-zero:store]
^- (unit [@da timebox:state-two:store])
=/ new-timebox=timebox:state-two:store
(convert-timebox-1 timebox)
?: =(0 ~(wyt by new-timebox))
~
`[time new-timebox]
::
++ convert-timebox-1
|= =timebox:state-zero:store
^- timebox:state-two:store
%- ~(gas by *timebox:state-two:store)
^- (list [index:state-two:store notification:state-two:store])
%+ murn
~(tap by timebox)
|= [=index:state-zero:store =notification:state-zero:store]
^- (unit [index:state-two:store notification:state-two:store])
=/ new-index=(unit index:state-two:store)
(convert-index-1 index)
=/ new-notification=(unit notification:state-two:store)
(convert-notification-1 notification)
?~ new-index ~
?~ new-notification ~
`[u.new-index u.new-notification]
::
++ convert-index-1
|= =index:state-zero:store
^- (unit index:state-two:store)
?+ -.index `index
%chat ~
::
%graph
=, index
`[%graph graph *resource module description ~]
==
::
++ convert-notification-1
|= =notification:state-zero:store
^- (unit notification:state-two:store)
?: ?=(%chat -.contents.notification)
~
`notification
--
::
++ on-watch
|= =path
^- (quip card _this)
?> (team:title [src our]:bowl)
|^
?+ path (on-watch:def path)
::
[%updates ~]
:_ this
[%give %fact ~ hark-update+!>(initial-updates)]~
==
::
++ initial-updates
^- update:store
:- %more
^- (list update:store)
:~ give-unreads
[%set-dnd dnd]
give-notifications
==
::
++ give-notifications
^- update:store
[%timebox ~ ~(tap by unread-notes)]
::
++ give-since-unreads
^- (list [stats-index:store stats:store])
%+ turn
~(tap by unreads-count)
|= [=stats-index:store count=@ud]
:* stats-index
[%count count]
(~(gut by last-seen) stats-index *time)
==
::
++ give-each-unreads
^- (list [stats-index:store stats:store])
%+ turn
~(tap by unreads-each)
|= [=stats-index:store indices=(set index:graph-store)]
:* stats-index
[%each indices]
(~(gut by last-seen) stats-index *time)
==
::
++ give-unreads
^- update:store
:- %unreads
;: weld
give-each-unreads
give-since-unreads
==
--
::
++ on-peek
|= =path
^- (unit (unit cage))
?+ path (on-peek:def path)
::
[%x %recent ?(%archive %inbox) @ @ ~]
=/ is-archive
=(%archive i.t.t.path)
=/ offset=@ud
(slav %ud i.t.t.t.path)
=/ length=@ud
(slav %ud i.t.t.t.t.path)
:^ ~ ~ %hark-update
!> ^- update:store
:- %more
%+ turn
%+ scag length
%+ slag offset
%- tap-nonempty:ha
?:(is-archive archive notifications)
|= [time=@da =timebox:store]
^- update:store
[%timebox `time ~(tap by timebox)]
==
::
++ on-poke
~/ %hark-store-poke
|= [=mark =vase]
^- (quip card _this)
|^
?> (team:title our.bowl src.bowl)
=^ cards state
?+ mark (on-poke:def mark vase)
%hark-action (hark-action !<(action:store vase))
%noun (poke-noun !<(* vase))
==
[cards this]
::
++ poke-noun
|= val=*
?+ val ~|(%bad-noun-poke !!)
%fix-dangling fix-dangling
%print ~&(+.state [~ state])
==
::
++ fix-dangling
=/ graphs get-keys:gra
:_ state
%+ roll
~(tap by unreads-each)
|= $: [=stats-index:store indices=(set index:graph-store)]
out=(list card)
==
?. ?=(%graph -.stats-index) out
?. (~(has in graphs) graph.stats-index)
:_(out (poke-us %remove-graph graph.stats-index))
%+ welp out
%+ turn
%+ skip
~(tap in indices)
|= =index:graph-store
(check-node-existence:gra graph.stats-index index)
|=(=index:graph-store (poke-us %read-each stats-index index))
::
++ poke-us
|= =action:store
^- card
[%pass / %agent [our dap]:bowl %poke hark-action+!>(action)]
::
++ hark-action
|= =action:store
^- (quip card _state)
abet:translate:(abed:poke-engine:ha action)
--
::
++ on-agent on-agent:def
::
++ on-leave on-leave:def
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?. ?=([%autoseen ~] wire)
(on-arvo:def wire sign-arvo)
`this
::
++ on-fail on-fail:def
--
|_ =bowl:gall
+* met ~(. metadata bowl)
++ poke-engine
|_ [in=action:store out=(list update:store) cards=(list card)]
++ poke-core .
::
++ abed
|= =action:store poke-core(in action)
::
++ abet
^- (quip card _state)
:_ state
%+ snoc (flop cards)
[%give %fact ~[/updates] %hark-update !>([%more (flop out)])]
::
++ give
|= =update:store poke-core(out [update out])
::
++ emit
|= =card poke-core(cards [card cards])
::
++ translate
^+ poke-core
?- -.in
::
%add-note (add-note +.in)
%archive (do-archive +.in)
::
%unread-count (unread-count +.in)
%read-count (read-count +.in)
::
%read-each (read-each +.in)
%unread-each (unread-each +.in)
::
%read-note (read-note +.in)
::
%seen-index (seen-index +.in)
::
%remove-graph (remove-graph +.in)
%read-graph (read-graph +.in)
%read-group (read-group +.in)
::
%set-dnd (set-dnd +.in)
%seen seen
%read-all read-all
::
==
::
:: +| %note
::
:: notification tracking
++ put-notifs
|= [time=@da =timebox:store]
poke-core(notifications (put:orm notifications time timebox))
::
++ add-note
|= [=index:store =notification:store]
^+ poke-core
=/ existing-notif
(~(get by unread-notes) index)
=/ new=notification:store
(merge-notification existing-notif notification)
=. unread-notes
(~(put by unread-notes) index new)
=/ timebox=@da
(~(gut by timeboxes) (to-stats-index:store index) current-timebox)
(give %added index new)
::
++ do-archive
|= [time=(unit @da) =index:store]
^+ poke-core
|^
?~(time archive-unread (archive-read u.time))
::
++ archive-unread
=. unread-notes
(~(del by unread-notes) index)
(give %archive ~ index)
::
++ archive-read
|= time=@da
=/ =timebox:store
(gut-orm notifications time)
=/ =notification:store
(~(got by timebox) index)
=/ new-timebox=timebox:store
(~(del by timebox) index)
=. poke-core
(put-notifs time new-timebox)
(give %archive `time index)
--
::
++ read-note
|= =index:store
=/ =notification:store
(~(got by unread-notes) index)
=. unread-notes
(~(del by unread-notes) index)
=/ =time
(~(gut by timeboxes) (to-stats-index:store index) current-timebox)
=/ =timebox:store
(gut-orm notifications time)
=/ existing-notif
(~(get by timebox) index)
=/ new=notification:store
(merge-notification existing-notif notification)
=. timebox
(~(put by timebox) index new)
=. notifications
(put:orm notifications time timebox)
(give %note-read time index)
::
::
:: +| %each
::
:: each unread tracking
::
++ unread-each
|= [=stats-index:store unread=index:graph-store time=@da]
=. poke-core (seen-index time stats-index)
%+ jub-unreads-each:(give %unread-each stats-index unread time)
stats-index
|= indices=(set index:graph-store)
(~(put ^in indices) unread)
::
++ read-index-each
|= [=stats-index:store ref=index:graph-store]
%- read-indices
%+ skim
~(tap ^in ~(key by unread-notes))
|= =index:store
?. (stats-index-is-index:store stats-index index) %.n
=/ not=notification:store
(~(got by unread-notes) index)
?. ?=(%graph -.index) %.n
?. ?=(%graph -.contents.not) %.n
(lien list.contents.not |=(p=post:post =(index.p ref)))
::
++ read-each
|= [=stats-index:store ref=index:graph-store]
=. timeboxes (~(put by timeboxes) stats-index now.bowl)
=. poke-core (read-index-each stats-index ref)
%+ jub-unreads-each:(give %read-each stats-index ref)
stats-index
|= indices=(set index:graph-store)
(~(del ^in indices) ref)
::
++ jub-unreads-each
|= $: =stats-index:store
f=$-((set index:graph-store) (set index:graph-store))
==
poke-core(unreads-each (jub stats-index f))
::
++ unread-count
|= [=stats-index:store time=@da]
=/ new-count
+((~(gut by unreads-count) stats-index 0))
=. unreads-count
(~(put by unreads-count) stats-index new-count)
(seen-index:(give %unread-count stats-index time) time stats-index)
::
++ read-count
|= =stats-index:store
=. unreads-count (~(put by unreads-count) stats-index 0)
=/ times=(list index:store)
(unread-for-stats-index stats-index)
=? timeboxes !(~(has by timeboxes) stats-index) (~(put by timeboxes) stats-index now.bowl)
(give:(read-indices times) %read-count stats-index)
::
++ read-indices
|= times=(list =index:store)
|-
?~ times poke-core
=/ core
(read-note i.times)
$(poke-core core, times t.times)
::
++ seen-index
|= [time=@da =stats-index:store]
=/ new-time=@da
(max time (~(gut by last-seen) stats-index 0))
=. last-seen
(~(put by last-seen) stats-index new-time)
(give %seen-index new-time stats-index)
::
++ get-stats-indices
|= rid=resource
%- ~(gas ^in *(set stats-index:store))
%+ skim
;: weld
~(tap ^in ~(key by unreads-count))
~(tap ^in ~(key by last-seen))
~(tap ^in ~(key by unreads-each))
==
|= =stats-index:store
?. ?=(%graph -.stats-index) %.n
=(graph.stats-index rid)
::
++ read-all-each
|= =stats-index:store
=/ refs=(list index:graph-store)
~(tap ^in (~(get ju unreads-each) stats-index))
|-
?~ refs poke-core
$(refs t.refs, poke-core (read-each stats-index i.refs))
::
++ read-graph
|= rid=resource
=/ indices=(list stats-index:store)
~(tap ^in (get-stats-indices rid))
|-
?~ indices poke-core
=* index i.indices
=? poke-core (~(has by unreads-count) index)
(read-count i.indices)
=? poke-core (~(has by unreads-each) index)
(read-all-each i.indices)
$(indices t.indices)
::
++ read-group
|= rid=resource
=/ graphs=(list resource)
(graphs-of-group:met rid)
|-
?~ graphs poke-core
=/ core=_poke-core (read-graph i.graphs)
$(graphs t.graphs, poke-core core)
::
++ remove-graph
|= rid=resource
|^
=/ indices (get-stats-indices rid)
=. poke-core
(give %remove-graph rid)
=. poke-core
(remove-notifications indices)
=. unreads-count
((dif-map-by-key ,@ud) unreads-count indices)
=. unreads-each
%+ (dif-map-by-key ,(set index:graph-store))
unreads-each indices
=. last-seen
((dif-map-by-key ,@da) last-seen indices)
poke-core
::
++ dif-map-by-key
|* value=mold
|= [=(map stats-index:store value) =(set stats-index:store)]
=/ to-remove ~(tap ^in set)
|-
?~ to-remove map
=. map
(~(del by map) i.to-remove)
$(to-remove t.to-remove)
::
++ remove-notifications
|= =(set stats-index:store)
^+ poke-core
=/ indices
~(tap ^in set)
|-
?~ indices poke-core
=/ times=(list =index:store)
(unread-for-stats-index i.indices)
=. poke-core
(read-indices times)
$(indices t.indices)
--
::
++ seen
=. poke-core
(read-indices ~(tap ^in ~(key by unread-notes)))
poke-core(current-timebox now.bowl, timeboxes ~)
::
++ read-all
=: unreads-count (~(run by unreads-count) _0)
unreads-each (~(run by unreads-each) _~)
notifications (~(run by notifications) _~)
==
(give:seen %read-all ~)
::
++ set-dnd
|= d=?
(give:poke-core(dnd d) %set-dnd d)
--
::
++ unread-for-stats-index
|= =stats-index:store
%+ skim ~(tap in ~(key by unread-notes))
(cury stats-index-is-index:store stats-index)
::
++ merge-notification
|= [existing=(unit notification:store) new=notification:store]
^- notification:store
?~ existing new
?- -.contents.u.existing
::
%graph
?> ?=(%graph -.contents.new)
u.existing(list.contents (weld list.contents.u.existing list.contents.new))
::
%group
?> ?=(%group -.contents.new)
u.existing(list.contents (weld list.contents.u.existing list.contents.new))
==
::
:: +key-orm: +key:by for ordered maps
++ key-orm
|= =notifications:store
^- (list @da)
(turn (tap:orm notifications) |=([@da *] +<-))
:: +jub-orm: combo +jab/+gut for ordered maps
:: TODO: move to zuse.hoon
++ jub-orm
|= [=notifications:store time=@da fun=$-(timebox:store timebox:store)]
^- notifications:store
=/ =timebox:store
(fun (gut-orm notifications time))
(put:orm notifications time timebox)
++ jub
|= [=stats-index:store f=$-((set index:graph-store) (set index:graph-store))]
^- (jug stats-index:store index:graph-store)
=/ val=(set index:graph-store)
(~(gut by unreads-each) stats-index ~)
(~(put by unreads-each) stats-index (f val))
:: +gut-orm: +gut:by for ordered maps
:: TODO: move to zuse.hoon
++ gut-orm
|= [=notifications:store time=@da]
^- timebox:store
(fall (get:orm notifications time) ~)
::
++ autoseen-interval ~h3
++ cancel-autoseen
^- card
[%pass /autoseen %arvo %b %rest (add current-timebox autoseen-interval)]
::
++ autoseen-timer
^- card
[%pass /autoseen %arvo %b %wait (add now.bowl autoseen-interval)]
::
++ scry
|* [=mold p=path]
?> ?=(^ p)
?> ?=(^ t.p)
.^(mold i.p (scot %p our.bowl) i.t.p (scot %da now.bowl) t.t.p)
::
++ give
|= [paths=(list path) update=update:store]
^- (list card)
[%give %fact paths [%hark-update !>(update)]]~
::
++ tap-nonempty
|= =notifications:store
^- (list [@da timebox:store])
%+ skim (tap:orm notifications)
|=([@da =timebox:store] !=(~(wyt by timebox) 0))
--

View File

@ -1,6 +1,8 @@
:: herm: stand-in for term.c with http interface
::
/+ default-agent, dbug, verb
/$ blit-to-json %blit %json
/$ json-to-blit %json %blit
=, jael
|%
+$ state-0 [%0 ~]
@ -11,33 +13,15 @@
%+ verb |
%- agent:dbug
^- agent:gall
=> |%
++ request-tube
|= [bowl:gall from=mark to=mark next=?]
^- card:agent:gall
:* %pass /tube/[from]/[to]
%arvo %c %warp
our q.byk ~
::
?: next
[%next %c da+now /[from]/[to]]
[%sing %c da+now /[from]/[to]]
==
--
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
::
++ on-init
^- (quip card:agent:gall _this)
:_ this
:: set up dill session subscription,
:: and ensure the tubes we use are in cache
:: set up dill session subscription
::
:~ [%pass [%view %$ ~] %arvo %d %view ~]
(request-tube bowl %blit %json |)
(request-tube bowl %json %belt |)
==
[[%pass [%view %$ ~] %arvo %d %view ~]~ this]
::
++ on-save !>([%0 ~])
++ on-load
@ -61,7 +45,9 @@
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card:agent:gall _this)
?+ wire !!
?+ wire (on-arvo:def wire sign-arvo)
[%tube *] [~ this] :: we no longer care about these
::
:: pass on dill blits for the session
::
[%view %$ ~]
@ -72,17 +58,6 @@
%+ turn p.sign-arvo
|= =blit:dill
[%give %fact [%session %$ ~]~ %blit !>(blit)]
::
:: ensure the tubes we need remain in cache
::
[%tube @ @ ~]
=* from i.t.wire
=* to i.t.t.wire
?. ?=([%clay %writ *] sign-arvo)
~| [%unexpected-sign [- +<]:sign-arvo]
!!
:_ this
[(request-tube bowl from to &)]~
==
::
++ on-poke

View File

@ -2,22 +2,27 @@
/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln
|%
+$ state
$: %15
drum=state:drum
helm=state:helm
kiln=state:kiln
==
$~ [%22 *state:drum *state:helm *state:kiln]
$>(%22 any-state)
::
+$ any-state
$% state
[ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
[%7 drum=state:drum helm=state:helm kiln=state-1:kiln]
[%8 drum=state:drum helm=state:helm kiln=state-1:kiln]
[%9 drum=state:drum helm=state:helm kiln=state-1:kiln]
[%10 drum=state:drum helm=state:helm kiln=state-1:kiln]
[%11 drum=state:drum helm=state:helm kiln=state-1:kiln]
[%12 drum=state:drum helm=state:helm kiln=state-1:kiln]
[%13 drum=state:drum helm=state:helm kiln=state-1:kiln]
[%14 drum=state:drum helm=state:helm kiln=state:kiln]
$% [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
[%7 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%8 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%9 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%10 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%11 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%12 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%13 drum=state-2:drum helm=state:helm kiln=state-1:kiln]
[%14 drum=state-2:drum helm=state:helm kiln=state-1:kiln]
[%15 drum=state-2:drum helm=state:helm kiln=state-2:kiln]
[%16 drum=state-4:drum helm=state:helm kiln=state-3:kiln]
[%17 drum=state-4:drum helm=state:helm kiln=state-4:kiln]
[%18 drum=state-4:drum helm=state:helm kiln=state-5:kiln]
[%19 drum=state-4:drum helm=state:helm kiln=state-6:kiln]
[%20 drum=state-4:drum helm=state:helm kiln=state-7:kiln]
[%21 drum=state-4:drum helm=state:helm kiln=state-8:kiln]
[%22 drum=state-4:drum helm=state:helm kiln=state-9:kiln]
==
+$ any-state-tuple
$: drum=any-state:drum
@ -44,7 +49,8 @@
++ on-init
^- step:agent:gall
=^ d drum.state on-init:drum-core
[d this]
=^ k kiln.state on-init:kiln-core
[:(welp d k) this]
::
++ on-leave on-leave:def
++ on-peek
@ -67,9 +73,9 @@
=-(?>(?=(%kiln -<) ->) (~(got by lac.old) %kiln))
==
==
=^ d drum.state (on-load:drum-core -.old drum.tup)
=^ h helm.state (on-load:helm-core -.old helm.tup)
=^ k kiln.state (on-load:kiln-core -.old kiln.tup)
=^ d drum.state (on-load:(drum bowl *state:drum) -.old drum.tup)
=^ h helm.state (on-load:(helm bowl *state:helm) -.old helm.tup)
=^ k kiln.state (on-load:(kiln bowl *state:kiln) -.old kiln.tup)
[:(welp d h k) this]
::
++ on-poke
@ -97,24 +103,23 @@
|= =path
^- step:agent:gall
?+ path (on-watch:def +<)
[%drum *] =^(c drum.state (peer:drum-core +<) [c this])
[%drum *] =^(c drum.state (peer:drum-core t.path) [c this])
[%kiln *] =^(c kiln.state (peer:kiln-core t.path) [c this])
==
::
++ on-agent
|= [=wire =sign:agent:gall]
|= [=wire syn=sign:agent:gall]
^- step:agent:gall
?+ wire ~|([%hood-bad-wire wire] !!)
[%drum *] =^(c drum.state (take-agent:drum-core +<) [c this])
[%helm *] =^(c helm.state (take-agent:helm-core +<) [c this])
[%kiln *] =^(c kiln.state (take-agent:kiln-core +<) [c this])
[%drum *] =^(c drum.state (take-agent:drum-core t.wire syn) [c this])
[%helm *] =^(c helm.state (take-agent:helm-core t.wire syn) [c this])
[%kiln *] =^(c kiln.state (take-agent:kiln-core t.wire syn) [c this])
==
:: TODO: symmetry between adding and stripping wire prefixes
::
++ on-arvo
|= [=wire syn=sign-arvo]
^- step:agent:gall
?+ wire ~|([%hood-bad-wire wire] !!)
[%drum *] =^(c drum.state (take-arvo:drum-core t.wire syn) [c this])
[%helm *] =^(c helm.state (take-arvo:helm-core t.wire syn) [c this])
[%kiln *] =^(c kiln.state (take-arvo:kiln-core t.wire syn) [c this])
==

View File

@ -1,5 +1,5 @@
/- spider
/+ libstrand=strand, default-agent, verb, server
/+ libstrand=strand, default-agent, verb, server, dbug
=, strand=strand:libstrand
~% %spider-top ..part ~
|%
@ -18,17 +18,35 @@
$: starting=(map yarn [=trying =vase])
running=trie
tid=(map tid yarn)
serving=(map tid [@ta =mark])
serving=(map tid [(unit @ta) =mark =desk])
==
::
+$ clean-slate-any
$^ clean-slate-ket
$% clean-slate-sig
clean-slate-1
clean-slate-2
clean-slate-3
clean-slate
==
::
+$ clean-slate
$: %4
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
serving=(map tid [(unit @ta) =mark =desk])
==
::
+$ clean-slate-3
$: %3
starting=(map yarn [=trying =vase])
running=(list yarn)
tid=(map tid yarn)
serving=(map tid [@ta =mark =desk])
==
::
+$ clean-slate-2
$: %2
starting=(map yarn [=trying =vase])
running=(list yarn)
@ -56,7 +74,7 @@
==
::
+$ start-args
[parent=(unit tid) use=(unit tid) file=term =vase]
[parent=(unit tid) use=(unit tid) =beak file=term =vase]
--
::
:: Trie operations
@ -135,6 +153,7 @@
(welp next-1 next-2)
--
::
%- agent:dbug
^- agent:gall
=| =state
=<
@ -145,8 +164,9 @@
spider-core +>
sc ~(. spider-core bowl)
def ~(. (default-agent this %|) bowl)
bec byk.bowl(r da+now.bowl)
::
++ on-init
++ on-init
^- (quip card _this)
:_ this
~[bind-eyre:sc]
@ -157,9 +177,11 @@
=+ !<(any=clean-slate-any old-state)
=? any ?=(^ -.any) (old-to-1 any)
=? any ?=(~ -.any) (old-to-1 any)
=^ upgrade-cards any
=^ upgrade-cards any
(old-to-2 any)
?> ?=(%2 -.any)
=. any (old-to-3 any)
=. any (old-to-4 any)
?> ?=(%4 -.any)
::
=. tid.state tid.any
=/ yarns=(list yarn)
@ -181,9 +203,9 @@
::
++ old-to-2
|= old=clean-slate-any
^- (quip card clean-slate)
?> ?=(?(%1 %2) -.old)
?: ?=(%2 -.old)
^- (quip card clean-slate-any)
?> ?=(?(%1 %2 %3 %4) -.old)
?: ?=(?(%2 %3 %4) -.old)
`old
:- ~[bind-eyre:sc]
:* %2
@ -192,6 +214,31 @@
tid.old
~
==
::
++ old-to-3
|= old=clean-slate-any
^- clean-slate-any
?> ?=(?(%2 %3 %4) -.old)
?: ?=(?(%3 %4) -.old)
old
:* %3
starting.old
running.old
tid.old
(~(run by serving.old) |=([id=@ta =mark] [id mark q.byk.bowl]))
==
++ old-to-4
|= old=clean-slate-any
^- clean-slate
?> ?=(?(%3 %4) -.old)
?: ?=(%4 -.old)
old
:* %4
starting.old
running.old
tid.old
(~(run by serving.old) |=([id=@ta =mark =desk] [`id mark q.byk.bowl]))
==
--
::
++ on-poke
@ -206,7 +253,7 @@
%spider-start (handle-start-thread:sc !<(start-args vase))
%spider-stop (handle-stop-thread:sc !<([tid ?] vase))
::
%handle-http-request
%handle-http-request
(handle-http-request:sc !<([@ta =inbound-request:eyre] vase))
==
[cards this]
@ -271,7 +318,7 @@
::
~% %spider-helper ..get-yarn ~
|_ =bowl:gall
::
++ bec `beak`byk.bowl(r da+now.bowl)
++ bind-eyre
^- card
[%pass /bind %arvo %e %connect [~ /spider] %spider]
@ -284,33 +331,26 @@
~/ %handle-http-request
|= [eyre-id=@ta =inbound-request:eyre]
^- (quip card _state)
?> authenticated.inbound-request
=/ url
::?> authenticated.inbound-request
=/ url
(parse-request-line:server url.request.inbound-request)
?> ?=([%spider @t @t @t ~] site.url)
=* input-mark i.t.site.url
=* thread i.t.t.site.url
=* output-mark i.t.t.t.site.url
?> ?=([%spider @t @t @t @t ~] site.url)
=* desk i.t.site.url
=* input-mark i.t.t.site.url
=* thread i.t.t.t.site.url
=* output-mark i.t.t.t.t.site.url
=/ =tid (new-thread-id thread)
=. serving.state
(~(put by serving.state) tid [eyre-id output-mark])
(~(put by serving.state) tid [`eyre-id output-mark desk])
:: TODO: speed this up somehow. we spend about 15ms in this arm alone
::
=+ .^
=tube:clay
%cc
/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/json/[input-mark]
==
=/ tube (convert-tube %json input-mark desk bowl)
?> ?=(^ body.request.inbound-request)
=/ body=json
(need (de-json:html q.u.body.request.inbound-request))
=/ input=vase
(slop !>(~) (tube !>(body)))
=/ =start-args
[~ `tid thread input]
=^ cards state
(handle-start-thread start-args)
[cards state]
=/ body=json (need (de-json:html q.u.body.request.inbound-request))
=/ input=vase (slop !>(~) (tube !>(body)))
=/ boc bec
=/ =start-args [~ `tid boc(q desk, r da+now.bowl) thread input]
(handle-start-thread start-args)
::
++ on-poke-input
|= input
@ -345,7 +385,7 @@
::
++ handle-start-thread
~/ %handle-start-thread
|= [parent-tid=(unit tid) use=(unit tid) file=term =vase]
|= [parent-tid=(unit tid) use=(unit tid) =beak file=term =vase]
^- (quip card ^state)
=/ parent-yarn=yarn
?~ parent-tid
@ -361,16 +401,19 @@
~| [%already-starting yarn]
!!
::
=? serving.state !(~(has by serving.state) new-tid)
(~(put by serving.state) new-tid [~ %noun q.beak])
::
=: starting.state (~(put by starting.state) yarn [%build vase])
tid.state (~(put by tid.state) new-tid yarn)
==
==
=/ pax=path
~| no-file-for-thread+file
(need (get-fit:clay [our q.byk da+now]:bowl %ted file))
(need (get-fit:clay beak %ted file))
:_ state
:_ ~
:+ %pass /build/[new-tid]
[%arvo %c %warp our.bowl %home ~ %sing %a da+now.bowl pax]
[%arvo %c %warp p.beak q.beak ~ %sing %a r.beak pax]
::
++ handle-build
~/ %handle-build
@ -432,7 +475,7 @@
^- (quip card ^state)
=/ m (strand ,vase)
?. (has-yarn running.state yarn)
%- (slog leaf+"spider got input for non-existent {<yarn>} 2" ~)
%- (slog leaf+"spider got input for non-existent {<yarn>}" ~)
`state
=/ =eval-form:eval:m
thread-form:(need (get-yarn running.state yarn))
@ -478,7 +521,7 @@
=/ moz (thread-say-fail tid term tang)
?. ?=([~ %build *] (~(get by starting.state) yarn))
moz
:_(moz [%pass /build/[tid] %arvo %c %warp our.bowl %home ~])
:_(moz [%pass /build/[tid] %arvo %c %warp our.bowl %base ~])
::
++ thread-say-fail
|= [=tid =term =tang]
@ -490,11 +533,13 @@
|= [=tid =term =tang]
^- (quip card ^state)
=- (fall - `state)
%+ bind
%+ bind
(~(get by serving.state) tid)
|= [eyre-id=@ta output=mark]
|= [eyre-id=(unit @ta) output=mark =desk]
:_ state(serving (~(del by serving.state) tid))
%+ give-simple-payload:app:server eyre-id
?~ eyre-id
~
%+ give-simple-payload:app:server u.eyre-id
^- simple-payload:http
:_ ~ :_ ~
?. ?=(http-error:spider term)
@ -520,16 +565,14 @@
|= [=tid =vase]
^- (quip card ^state)
=- (fall - `state)
%+ bind
%+ bind
(~(get by serving.state) tid)
|= [eyre-id=@ta output=mark]
=+ .^
=tube:clay
%cc
/(scot %p our.bowl)/[q.byk.bowl]/(scot %da now.bowl)/[output]/json
==
|= [eyre-id=(unit @ta) output=mark =desk]
?~ eyre-id
`state
=/ tube (convert-tube output %json desk bowl)
:_ state(serving (~(del by serving.state) tid))
%+ give-simple-payload:app:server eyre-id
%+ give-simple-payload:app:server u.eyre-id
(json-response:gen:server !<(json (tube vase)))
::
++ thread-done
@ -560,6 +603,7 @@
=/ =tid (yarn-to-tid yarn)
=: running.state (del-yarn running.state yarn)
tid.state (~(del by tid.state) tid)
serving.state (~(del by serving.state) (yarn-to-tid yarn))
==
:_ state
%+ murn ~(tap by wex.bowl)
@ -576,14 +620,14 @@
|= [=yarn =bowl:gall]
^- bowl:spider
:* our.bowl
src.bowl
src.bowl
(yarn-to-tid yarn)
(yarn-to-parent yarn)
wex.bowl
sup.bowl
eny.bowl
now.bowl
byk.bowl
(yarn-to-byk yarn bowl)
==
::
++ yarn-to-tid
@ -602,7 +646,25 @@
~
`i.t.nary
::
++ yarn-to-byk
|= [=yarn =bowl:gall]
=/ [* * =desk]
~| "no desk associated with {<tid>}"
%- ~(got by serving.state) (yarn-to-tid yarn)
=/ boc bec
boc(q desk)
::
++ clean-state
!> ^- clean-slate
2+state(running (turn (tap-yarn running.state) head))
4+state(running (turn (tap-yarn running.state) head))
::
++ convert-tube
|= [from=mark to=mark =desk =bowl:gall]
.^
tube:clay
%cc
/(scot %p our.bowl)/[desk]/(scot %da now.bowl)/[from]/[to]
==
--

11
pkg/arvo/desk.bill Normal file
View File

@ -0,0 +1,11 @@
:~ %acme
%azimuth
%dbug
%dojo
%eth-watcher
%hood
%herm
%lens
%ping
%spider
==

11
pkg/arvo/gen/agents.hoon Normal file
View File

@ -0,0 +1,11 @@
/- hood
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[=desk ~] ~]
==
:- %tang
%+ turn (get-apps-have:hood p.bec desk now)
|= [=dude:gall live=?]
^- tank
=/ liv ?:(live "running " "archived")
[%leaf "status: {liv} {<dude>}"]

View File

@ -9,17 +9,43 @@
!:
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
arg=$@(~ [top=path ~])
::
:: arg: desks to build pill from
::
:: list of desks. defaults to [%base]~.
:: the first desk in this list will become the pill's base desk.
:: optionally, the first desk may be replaced with a fully
:: qualified path to the new boot system (typically in sys).
:: the rest of the desks will be installed through kiln.
::
$= arg
$@ ~
$: base=$@(desk [@ta @ta @ta path])
rest=(list desk)
==
::
~
==
:- %boot-pill
^- pill:pill
::
:: sys: root path to boot system, `/~me/[desk]/now/sys`
:: bas: root path to boot system' desk
:: dez: secondary desks and their root paths
::
=/ sys=path
?^ arg top.arg
/(scot %p p.bec)/[q.bec]/(scot %da now)/sys
?: ?=([^ *] arg)
`path`base.arg
=/ =desk
?~ arg %base
?>(?=(@ base.arg) base.arg)
/(scot %p p.bec)/[desk]/(scot %da now)/sys
=/ bas=path
(scag 3 sys)
=/ dez=(list [desk path])
?~ arg ~
%+ turn rest.arg
|= =desk
[desk /(scot %p p.bec)/[desk]/(scot %da now)]
::
:: compiler-source: hoon source file producing compiler, `sys/hoon`
::
@ -52,10 +78,11 @@
==
:: a pill is a 3-tuple of event-lists: [boot kernel userspace]
::
=/ bas=path (flop (tail (flop sys)))
:+ %pill %brass
:+ boot-ova
:~ (boot-ovum:pill compiler-source arvo-source)
(file-ovum2:pill bas)
==
[(file-ovum:pill bas) ~]
%+ turn
(snoc dez [%base bas])
file-ovum:pill

View File

@ -0,0 +1,10 @@
:: +desk-jam: jam ankh from desk
::
/+ jammer=desk-jam
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[=desk ~]
~
==
:- %jam
(jam-desk:jammer p.bec desk now)

View File

@ -0,0 +1,7 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
~
force=_|
except=(set desk)
==
[%kiln-bump except force]

View File

@ -0,0 +1,14 @@
:: |install: install the .rem desk from .her into local .lac desk
::
:: > |install ~zod %landscape
:: installs ~zod's %landscape desk into our %landscape desk.
::
:: > |install ~zod %landscape, =local %portrait
:: installs ~zod's %landscape desk into our %portrait desk.
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[her=@p rem=desk ~] local=@tas]
==
=/ loc=desk ?:(=(%$ local) rem local)
[%kiln-install loc her rem]

View File

@ -7,11 +7,21 @@
::::
::
:- %say
=> |%
+$ bath
$@ desk
(lest knot)
--
|= $: [now=@da eny=@uvJ bec=beak]
[[pax=path pot=$@(~ [v=@tas ~])] ~]
[=bath pot=$@(~ [v=@tas ~])]
~
==
?~ pot
=+ bem=(need (de-beam pax))
$(pot ~[?^(s.bem (rear s.bem) q.bem)])
:- %kiln-mount
[pax v.pot]
=/ bem=beam
?@ bath [bec(q bath) /]
(need (de-beam `path`bath))
::
=/ =desk
?^ pot v.pot
?^(s.bem (rear s.bem) q.bem)
::
[%kiln-mount (en-beam bem) desk]

View File

@ -0,0 +1,34 @@
:: |nuke: wipe agent state & subscriptions after confirmation
::
/+ *generators
:- %ask
|= $: [now=@da eny=@uvJ bec=beak]
[=term ~]
[desk=_| hard=_|]
==
?: hard (produce %kiln-nuke term desk)
=/ m1
'nuking agents will permanently delete all their state and subscriptions.'
=/ m2
'if other agents depend on the one(s) you nuke, \
/their behavior could be negatively impacted. \
/if you do not understand the risks, you may \
/want to contact the agent\'s developers.'
=/ m3
%+ rap 3
:~ 'are you sure you want to continue and nuke '
::
?. desk (cat 3 '%' term)
(cat 3 'all agents in ' term)
::
'?'
==
::NOTE yes, printing order is weird
%+ print m3
%+ print m2
%+ print m1
%+ prompt [%& %prompt "nuke? (y/N) "]
|= in=tape
?. |(=("y" in) =("Y" in) =("yes" in))
no-product
(produce %kiln-nuke term desk)

View File

@ -8,11 +8,11 @@
::
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[arg=?(~ [%disable ~] [her=@p sud=@tas ~]) ~]
arg=?([%disable ~] [her=@p sud=?(~ [@tas ~])])
~
==
?~ arg
:- %kiln-ota-info ~
:- %kiln-ota
:- %kiln-install
?: ?=([%disable ~] arg)
~
`[her sud]:arg
[%base p.bec %base]
:+ %base her.arg
?@(sud.arg %kids -.sud.arg)

View File

@ -0,0 +1,5 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[=desk ~] ~]
==
[%kiln-pause desk]

View File

@ -0,0 +1,16 @@
/- hood
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
$: =desk
arg=(list [? dude:gall])
==
liv=_&
==
:- %kiln-rein
:- desk
%+ roll arg
=| =rein:hood
|: [*[on=? =dude:gall] rein(liv liv)]
?: on
rein(add (~(put in add.rein) dude))
rein(sub (~(put in sub.rein) dude))

View File

@ -0,0 +1,5 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[=desk ~] ~]
==
[%kiln-resume desk]

View File

@ -0,0 +1,5 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[=desk ~] ~]
==
[%kiln-revive desk]

View File

@ -0,0 +1,5 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[=desk ~] ~]
==
[%kiln-suspend desk]

View File

@ -0,0 +1,5 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[[=desk ~] ~]
==
[%kiln-uninstall desk]

View File

@ -2,6 +2,7 @@
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
~
~
nice=?
==
[%kick %kick]
[%kick nice]

View File

@ -0,0 +1,15 @@
/- *bill
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[=desk ~]
~
==
:- %tang
%- flop ^- tang
=/ pax=path /(scot %p p.bec)/[desk]/(scot %da now)
=+ .^([lal=@tas num=@ud] cx+(weld pax /sys/kelvin))
:~ 'sys.kelvin:'
leaf/"[%{<lal>} %{<num>}]"
'desk.bill:'
(sell !>(.^(bill cx+(weld pax /desk/bill))))
==

View File

@ -12,16 +12,43 @@
!:
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
arg=$@(~ [top=path ~])
::
:: arg: desks to build pill from
::
:: list of desks. defaults to [%base]~.
:: the first desk in this list will become the pill's base desk.
:: optionally, the first desk may be replaced with a fully
:: qualified path to the new boot system (typically in sys).
:: the rest of the desks will be installed through kiln.
::
$= arg
$@ ~
$: base=$@(desk [@ta @ta @ta path])
rest=(list desk)
==
::
dub=_|
==
:- %boot-pill
^- pill:pill
:: sys: root path to boot system, `/~me/[desk]/now/sys`
:: bas: root path to boot system' desk
:: dez: secondary desks and their root paths
::
=/ sys=path
?^ arg top.arg
/(scot %p p.bec)/[q.bec]/(scot %da now)/sys
?: ?=([^ *] arg)
`path`base.arg
=/ =desk
?~ arg %base
?>(?=(@ base.arg) base.arg)
/(scot %p p.bec)/[desk]/(scot %da now)/sys
=/ bas=path
(scag 3 sys)
=/ dez=(list [desk path])
?~ arg ~
%+ turn rest.arg
|= =desk
[desk /(scot %p p.bec)/[desk]/(scot %da now)]
::
=/ compiler-path (weld sys /hoon)
=/ arvo-path (weld sys /arvo)
@ -65,9 +92,10 @@
=< q
%^ spin
^- (list ovum)
:~ (boot-ovum:pill compiler-src arvo-src)
(file-ovum2:pill (flop (tail (flop sys))))
==
:- (boot-ovum:pill compiler-src arvo-src)
%+ turn
(snoc (turn dez tail) bas)
file-ovum2:pill
.*(0 arvo-formula)
|= [ovo=ovum ken=*]
[~ (slum ken [now ovo])]
@ -99,5 +127,6 @@
::
:+ %pill %solid
:+ boot-ova ~
=/ bas (flop (tail (flop sys)))
[(file-ovum:pill bas) ~]
%+ turn
(snoc dez [%base bas])
file-ovum:pill

View File

@ -1,4 +1,7 @@
:: Start a thread
:- %say
|= [* [name=term vase=$@(~ [vase ~])] ~]
[%spider-start ~ ~ name ?~(vase *^vase -.vase)]
|= $: [now=@da eny=@uvJ bec=beak]
[name=term vase=$@(~ [vase ~])]
~
==
[%spider-start ~ ~ bec name ?~(vase *^vase -.vase)]

View File

@ -1,76 +0,0 @@
:: Print useful diagnostic information
::
:: base-hash: loosely, the most recent successfully applied update.
:: Technically, the mergebase of %home with OTA source
:: sour-hash: most recently downloaded update (not necessarily applied)
:: home-hash: hash of %home desk, which may differ if you have changed
:: it, for example with notebooks or 3rd party apps
:: kids-hash: hash of the %kids desk, which is what you serve to your
:: children
:: glob-hash: hash of the glob, which is the js for landscape
::
/- glob
/+ version
:- %say
|= [[now=time * bec=beak] ~ ~]
=* our p.bec
=/ sponsor (sein:title our now our)
:- %noun
=<
:~
[%base-hash (base-hash:version our now)]
[%sour-hash sour-hash]
[%home-hash .^(@uv %cz (pathify ~.home ~))]
[%kids-hash .^(@uv %cz (pathify ~.kids ~))]
[%glob-hash glob-state]
::
(info %our our)
(info %sponsor sponsor)
(info %dopzod ~dopzod)
::
["Compare lifes and rifts to values here:"]
["https://etherscan.io/address/azimuth.eth#readContract"]
[" life - getKeyRevisionNumber"]
[" rift - getContinuityNumber"]
==
|%
++ pathify
|= [a=@ta b=(unit ship)]
^- path
=/ o=@ta (scot %p our)
=/ n=@ta (scot %da now)
?~ b ~[o a n]
~[o a n (scot %p u.b)]
::
++ info
|= [=term =ship]
:: unitized life and rift
=/ lyfe .^((unit @ud) %j (pathify ~.lyfe `ship))
=/ ryft .^((unit @ud) %j (pathify ~.ryft `ship))
:* term
ship=ship
point=(crip (slag 2 (scow %ui ship)))
:: report as units
life=lyfe
rift=ryft
==
::
++ sour-hash
=+ .^ ota=(unit [=ship =desk =aeon:clay])
%gx /(scot %p our)/hood/(scot %da now)/kiln/ota/noun
==
?~ ota
*@uv
=/ parent (scot %p ship.u.ota)
=+ .^(=cass:clay %cs /[parent]/[desk.u.ota]/1/late/foo)
.^(@uv %cz /[parent]/[desk.u.ota]/(scot %ud ud.cass))
::
++ glob-state
^- (list [path @uv @tas])
=+ !< [@ud =globs:glob]
.^(vase %gx (weld (pathify ~.glob ~) /dbug/state/noun))
%+ turn ~(tap by globs)
|= [srv=path hash=@uv glob=(unit [? *])]
^- [path @uv @tas]
[srv hash ?~(glob %waiting ?:(-.u.glob %done %trying))]
--

1
pkg/arvo/gen/trouble.hoon Symbolic link
View File

@ -0,0 +1 @@
vats.hoon

6
pkg/arvo/gen/vats.hoon Normal file
View File

@ -0,0 +1,6 @@
/- *hood
:- %say
|= $: [now=@da eny=@uvJ bec=beak]
[arg=~ ~]
==
[%tang (report-vats p.bec now)]

View File

@ -1,135 +0,0 @@
=>
|%
++ card card:agent:gall
--
::
|_ =bowl:gall
++ scry
|= [desk=@tas =path]
%+ weld
/(scot %p our.bowl)/[desk]/(scot %da now.bowl)
path
::
++ pass
|_ =wire
++ poke
|= [=dock =cage]
[%pass wire %agent dock %poke cage]
::
++ poke-our
|= [app=term =cage]
^- card
(poke [our.bowl app] cage)
::
++ poke-self
|= =cage
^- card
(poke-our dap.bowl cage)
::
++ arvo
|= =note-arvo
^- card
[%pass wire %arvo note-arvo]
::
++ watch
|= [=dock =path]
[%pass (watch-wire path) %agent dock %watch path]
::
++ watch-our
|= [app=term =path]
(watch [our.bowl app] path)
::
++ watch-wire
|= =path
^+ wire
?. ?=(~ wire)
wire
agentio-watch+path
::
++ leave
|= =dock
[%pass wire %agent dock %leave ~]
::
++ leave-our
|= app=term
(leave our.bowl app)
::
++ leave-path
|= [=dock =path]
=. wire
(watch-wire path)
(leave dock)
::
++ wait
|= p=@da
(arvo %b %wait p)
::
++ rest
|= p=@da
(arvo %b %wait p)
::
++ warp
|= [wer=ship =riff:clay]
(arvo %c %warp wer riff)
::
++ warp-our
|= =riff:clay
(warp our.bowl riff)
::
:: right here, right now
++ warp-slim
|= [genre=?(%sing %next) =care:clay =path]
=/ =mood:clay
[care r.byk.bowl path]
=/ =rave:clay
?:(?=(%sing genre) [genre mood] [genre mood])
(warp-our q.byk.bowl `rave)
--
::
++ fact-curry
|* [=mark =mold]
|= [paths=(list path) fac=mold]
(fact mark^!>(fac) paths)
::
++ fact-kick
|= [=path =cage]
^- (list card)
:~ (fact cage ~[path])
(kick ~[path])
==
::
++ fact-init
|= =cage
^- card
[%give %fact ~ cage]
::
++ fact-init-kick
|= =cage
^- (list card)
:~ (fact cage ~)
(kick ~)
==
::
++ fact
|= [=cage paths=(list path)]
^- card
[%give %fact paths cage]
::
++ fact-all
|= =cage
^- (unit card)
=/ paths=(list path)
%+ turn ~(tap by sup.bowl)
|= [duct ship =path]
path
?~ paths ~
`[%give %fact paths cage]
::
++ kick
|= paths=(list path)
[%give %kick paths ~]
::
++ kick-only
|= [=ship paths=(list path)]
[%give %kick paths `ship]
--

1
pkg/arvo/lib/agentio.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/agentio.hoon

View File

@ -87,7 +87,7 @@
0x223c.067f.8cf2.8ae1.73ee.5caf.ea60.ca44.c335.fecb
::
++ ecliptic
0x6ac0.7b7c.4601.b5ce.11de.8dfe.6335.b871.c7c4.dd4d
0xa5b6.109a.d2d3.5191.b3bc.32c0.0e45.26be.56fe.321f
::
++ linear-star-release
0x86cd.9cd0.992f.0423.1751.e376.1de4.5cec.ea5d.1801

View File

@ -1,146 +0,0 @@
/- rpc=json-rpc
/+ ethereum, azimuth, strandio
=, strand=strand:strandio
=, jael
|%
++ tract azimuth:contracts:azimuth
++ fetch-point
|= [url=@ta who=ship]
=/ m (strand ,point:azimuth)
^- form:m
=/ =request:rpc:ethereum
:+ %eth-call
=- [from=~ to=tract gas=~ price=~ value=~ data=-]
(encode-call:rpc:ethereum 'points(uint32)' [%uint `@`who]~)
[%label %latest]
;< jon=json bind:m (request-rpc url `'point' request)
=/ res=cord (so:dejs:format jon)
=/ =point:eth-noun:azimuth
(decode-results:abi:ethereum res point:eth-type:azimuth)
::
=/ =request:rpc:ethereum
:+ %eth-call
=- [from=~ to=tract gas=~ price=~ value=~ data=-]
(encode-call:rpc:ethereum 'rights(uint32)' [%uint `@`who]~)
[%label %latest]
;< jon=json bind:m (request-rpc url `'deed' request)
=/ res=cord (so:dejs:format jon)
=/ =deed:eth-noun:azimuth
(decode-results:abi:ethereum res deed:eth-type:azimuth)
::
(pure:m (point-from-eth:azimuth who point deed))
::
++ request-rpc
|= [url=@ta id=(unit @t) req=request:rpc:ethereum]
=/ m (strand ,json)
^- form:m
%+ (retry json) `10
=/ m (strand ,(unit json))
^- form:m
|^
=/ =request:http
:* method=%'POST'
url=url
header-list=['Content-Type'^'application/json' ~]
^= body
%- some %- as-octt:mimes:html
%- en-json:html
(request-to-json:rpc:ethereum id req)
==
;< ~ bind:m (send-request:strandio request)
;< rep=(unit client-response:iris) bind:m
take-maybe-response:strandio
?~ rep
(pure:m ~)
(parse-response u.rep)
::
++ parse-response
|= =client-response:iris
=/ m (strand ,(unit json))
^- form:m
?> ?=(%finished -.client-response)
?~ full-file.client-response
(pure:m ~)
=/ body=@t q.data.u.full-file.client-response
=/ jon=(unit json) (de-json:html body)
?~ jon
(pure:m ~)
=, dejs-soft:format
=/ array=(unit (list response:rpc))
((ar parse-one-response) u.jon)
?~ array
=/ res=(unit response:rpc) (parse-one-response u.jon)
?~ res
(strand-fail:strandio %request-rpc-parse-error >id< ~)
?: ?=(%error -.u.res)
(strand-fail:strandio %request-rpc-error >id< >+.res< ~)
?. ?=(%result -.u.res)
(strand-fail:strandio %request-rpc-fail >u.res< ~)
(pure:m `res.u.res)
(strand-fail:strandio %request-rpc-batch >%not-implemented< ~)
:: (pure:m `[%batch u.array])
::
++ parse-one-response
|= =json
^- (unit response:rpc)
=/ res=(unit [@t ^json])
%. json
=, dejs-soft:format
(ot id+so result+some ~)
?^ res `[%result u.res]
~| parse-one-response=json
:+ ~ %error %- need
%. json
=, dejs-soft:format
(ot id+so error+(ot code+no message+so ~) ~)
--
::
++ retry
|* result=mold
|= [crash-after=(unit @ud) computation=_*form:(strand (unit result))]
=/ m (strand ,result)
=| try=@ud
|- ^- form:m
=* loop $
?: =(crash-after `try)
(strand-fail:strandio %retry-too-many ~)
;< ~ bind:m (backoff:strandio try ~m1)
;< res=(unit result) bind:m computation
?^ res
(pure:m u.res)
loop(try +(try))
::
++ get-latest-block
|= url=@ta
=/ m (strand ,block)
^- form:m
;< =json bind:m (request-rpc url `'block number' %eth-block-number ~)
(get-block-by-number url (parse-eth-block-number:rpc:ethereum json))
::
++ get-block-by-number
|= [url=@ta =number:block]
=/ m (strand ,block)
^- form:m
|^
;< =json bind:m
(request-rpc url `'block by number' %eth-get-block-by-number number |)
=/ =block (parse-block json)
?. =(number number.id.block)
(strand-fail:strandio %reorg-detected >number< >block< ~)
(pure:m block)
::
++ parse-block
|= =json
^- block
=< [[&1 &2] |2]
^- [@ @ @]
~| json
%. json
=, dejs:format
%- ot
:~ hash+parse-hex-result:rpc:ethereum
number+parse-hex-result:rpc:ethereum
'parentHash'^parse-hex-result:rpc:ethereum
==
--
--

1
pkg/arvo/lib/azimuthio.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/azimuthio.hoon

View File

@ -1,263 +0,0 @@
/- bc=bitcoin
/+ bcu=bitcoin-utils
~% %bip-158-top ..part ~
|%
++ params
|%
++ p 19
++ m 784.931
--
::
++ siphash
~/ %siphash
|= [k=byts m=byts]
^- byts
|^
?> =(wid.k 16)
?> (lte (met 3 dat.k) wid.k)
?> (lte (met 3 dat.m) wid.m)
=. k (flim:sha k)
=. m (flim:sha m)
(flim:sha (fin (comp m (init dat.k))))
:: Initialise internal state
::
++ init
|= k=@
^- [@ @ @ @]
=/ k0=@ (end [6 1] k)
=/ k1=@ (cut 6 [1 1] k)
:^ (mix k0 0x736f.6d65.7073.6575)
(mix k1 0x646f.7261.6e64.6f6d)
(mix k0 0x6c79.6765.6e65.7261)
(mix k1 0x7465.6462.7974.6573)
::
:: Compression rounds
++ comp
|= [m=byts v=[v0=@ v1=@ v2=@ v3=@]]
^- [@ @ @ @]
=/ len=@ud (div wid.m 8)
=/ last=@ (lsh [3 7] (mod wid.m 256))
=| i=@ud
=| w=@
|-
=. w (cut 6 [i 1] dat.m)
?: =(i len)
=. v3.v (mix v3.v (mix last w))
=. v (rnd (rnd v))
=. v0.v (mix v0.v (mix last w))
v
%= $
v =. v3.v (mix v3.v w)
=. v (rnd (rnd v))
=. v0.v (mix v0.v w)
v
i (add i 1)
==
::
:: Finalisation rounds
++ fin
|= v=[v0=@ v1=@ v2=@ v3=@]
^- byts
=. v2.v (mix v2.v 0xff)
=. v (rnd (rnd (rnd (rnd v))))
:- 8
:(mix v0.v v1.v v2.v v3.v)
::
:: Sipround
++ rnd
|= [v0=@ v1=@ v2=@ v3=@]
^- [@ @ @ @]
=. v0 (~(sum fe 6) v0 v1)
=. v2 (~(sum fe 6) v2 v3)
=. v1 (~(rol fe 6) 0 13 v1)
=. v3 (~(rol fe 6) 0 16 v3)
=. v1 (mix v1 v0)
=. v3 (mix v3 v2)
=. v0 (~(rol fe 6) 0 32 v0)
=. v2 (~(sum fe 6) v2 v1)
=. v0 (~(sum fe 6) v0 v3)
=. v1 (~(rol fe 6) 0 17 v1)
=. v3 (~(rol fe 6) 0 21 v3)
=. v1 (mix v1 v2)
=. v3 (mix v3 v0)
=. v2 (~(rol fe 6) 0 32 v2)
[v0 v1 v2 v3]
--
:: +str: bit streams
:: read is from the front
:: write appends to the back
::
++ str
~% %str ..params ~
|%
++ read-bit
~/ %read-bit
|= s=bits:bc
^- [bit=@ub rest=bits:bc]
?> (gth wid.s 0)
:+ ?:((gth wid.s (met 0 dat.s)) 0b0 0b1)
(dec wid.s)
(end [0 (dec wid.s)] dat.s)
::
::
++ read-bits
~/ %read-bits
|= [n=@ s=bits:bc]
^- [bits:bc rest=bits:bc]
=/ r=@ (sub wid.s n)
:- n^(cut 0 [r n] dat.s)
r^(cut 0 [0 r] dat.s)
::
++ write-bits
~/ %write-bits
|= [s1=bits:bc s2=bits:bc]
^- bits:bc
[(add wid.s1 wid.s2) (can 0 ~[s2 s1])]
--
:: +gol: Golomb-Rice encoding/decoding
::
++ gol
~% %gol ..params ~
|%
:: +en: encode x and append to end of s
:: - s: bits stream
:: - x: number to add to the stream
:: - p: golomb-rice p param
::
++ en
~/ %en
|= [s=bits:bc x=@ p=@]
^- bits:bc
=+ q=(rsh [0 p] x)
=+ unary=[+(q) (lsh [0 1] (dec (bex q)))]
=+ r=[p (end [0 p] x)]
%+ write-bits:str s
(write-bits:str unary r)
::
++ de
~/ %de
|= [s=bits:bc p=@]
^- [delta=@ rest=bits:bc]
|^ ?> (gth wid.s 0)
=^ q s (get-q s)
=^ r s (read-bits:str p s)
[(add dat.r (lsh [0 p] q)) s]
::
++ get-q
|= s=bits:bc
=| q=@
=^ first-bit s (read-bit:str s)
|-
?: =(0 first-bit) [q s]
=^ b s (read-bit:str s)
$(first-bit b, q +(q))
--
--
:: +hsh
::
++ hsh
~% %hsh ..params ~
|%
:: +to-range
:: - item: scriptpubkey to hash
:: - f: N*M
:: - k: key for siphash (end of blockhash, reversed)
::
++ to-range
~/ %to-range
|= [item=byts f=@ k=byts]
^- @
(rsh [0 64] (mul f (rev 3 (siphash k item))))
:: +set-construct: return sorted hashes of scriptpubkeys
::
++ set-construct
|= [items=(list byts) k=byts f=@]
^- (list @)
%+ sort
%+ turn items
|= item=byts
(to-range item f k)
lth
--
::
++ parse-filter
~/ %parse-filter
|= filter=hexb:bc
^- [n=@ux gcs-set=bits:bc]
=/ n n:(de:csiz:bcu filter)
=/ lead=@ ?:(=(1 wid.n) 1 +(wid.n))
:- dat.n
[(mul 8 (sub wid.filter lead)) `@ub`dat:(drop:byt:bcu lead filter)]
:: +to-key: blockhash (little endian) to key for siphash
::
++ to-key
~/ %to-key
|= blockhash=tape
^- byts
%+ take:byt:bcu 16
%- flip:byt:bcu
(from-cord:hxb:bcu (crip blockhash))
:: +match: whether block filter matches *any* target scriptpubkeys
:: - filter: full block filter, with leading N
:: - k: key for siphash (end of blockhash, reversed)
:: - targets: scriptpubkeys to match
::
++ match
~/ %match
|= [filter=hexb:bc k=byts targets=(list byts)]
^- ?
=/ [p=@ m=@] [p:params m:params]
=/ [n=@ux gcs-set=bits:bc] (parse-filter filter)
=+ target-hs=(set-construct:hsh targets k (mul n m))
=+ last-val=0
|-
?~ target-hs %.n
?: =(last-val i.target-hs)
%.y
?: (gth last-val i.target-hs)
$(target-hs t.target-hs)
:: last-val is less than target: check next val in GCS, if any
::
?: (lth wid.gcs-set p) %.n
=^ delta gcs-set
(de:gol gcs-set p)
$(last-val (add delta last-val))
:: +all-match: returns all target byts that match
:: - filter: full block filter, with leading N
:: - targets: scriptpubkeys to match
::
++ all-match
~/ %all-match
|= [filter=hexb:bc blockhash=hexb:bc targets=(list [address:bc byts])]
^- (set [address:bc hexb:bc])
=/ k (to-key (trip (to-cord:hxb:bcu blockhash)))
%- ~(gas in *(set [address:bc hexb:bc]))
=/ [p=@ m=@] [p:params m:params]
=/ [n=@ux gcs-set=bits:bc] (parse-filter filter)
=/ target-map=(map @ [address:bc hexb:bc])
%- ~(gas by *(map @ [address:bc hexb:bc]))
%+ turn targets
|= [a=address:bc t=hexb:bc]
[(to-range:hsh t (mul n m) k) a t]
=+ target-hs=(sort ~(tap in ~(key by target-map)) lth)
=+ last-val=0
=| matches=(list @)
|-
?~ target-hs
(murn matches ~(get by target-map))
?: =(last-val i.target-hs)
%= $
target-hs t.target-hs
matches [last-val matches]
==
?: (gth last-val i.target-hs)
$(target-hs t.target-hs)
:: last-val is less than target: get next val in GCS, if any
::
?: (lth wid.gcs-set p)
(murn matches ~(get by target-map))
=^ delta gcs-set
(de:gol gcs-set p)
$(last-val (add delta last-val))
::
--

1
pkg/arvo/lib/bip/b158.hoon Symbolic link
View File

@ -0,0 +1 @@
../../../base-dev/lib/bip/b158.hoon

View File

@ -1,144 +0,0 @@
:: BIP173: Bech32 Addresses
:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
::
:: Heavily copies:
:: https://github.com/bitcoinjs/bech32/blob/master/index.js
::
/- sur=bitcoin
/+ bcu=bitcoin-utils
=, sur
=, bcu
|%
++ prefixes
^- (map network tape)
(my [[%main "bc"] [%testnet "tb"] ~])
++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l"
+$ raw-decoded [hrp=tape data=(list @) checksum=(list @)]
:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js
::
++ polymod
|= values=(list @)
|^ ^- @
=/ gen=(list @ux)
~[0x3b6a.57b2 0x2650.8e6d 0x1ea1.19fa 0x3d42.33dd 0x2a14.62b3]
=/ chk=@ 1
|- ?~ values chk
=/ top (rsh [0 25] chk)
=. chk
(mix i.values (lsh [0 5] (dis chk 0x1ff.ffff)))
$(values t.values, chk (update-chk chk top gen))
::
++ update-chk
|= [chk=@ top=@ gen=(list @ux)]
=/ is (gulf 0 4)
|- ?~ is chk
?: =(1 (dis 1 (rsh [0 i.is] top)))
$(is t.is, chk (mix chk (snag i.is gen)))
$(is t.is)
--
::
++ expand-hrp
|= hrp=tape
^- (list @)
=/ front (turn hrp |=(p=@tD (rsh [0 5] p)))
=/ back (turn hrp |=(p=@tD (dis 31 p)))
(zing ~[front ~[0] back])
::
++ verify-checksum
|= [hrp=tape data-and-checksum=(list @)]
^- ?
%- |=(a=@ =(1 a))
%- polymod
(weld (expand-hrp hrp) data-and-checksum)
::
++ checksum
|= [hrp=tape data=(list @)]
^- (list @)
:: xor 1 with the polymod
::
=/ pmod=@
%+ mix 1
%- polymod
(zing ~[(expand-hrp hrp) data (reap 6 0)])
%+ turn (gulf 0 5)
|=(i=@ (dis 31 (rsh [0 (mul 5 (sub 5 i))] pmod)))
::
++ charset-to-value
|= c=@tD
^- (unit @)
(find ~[c] charset)
++ value-to-charset
|= value=@
^- (unit @tD)
?: (gth value 31) ~
`(snag value charset)
::
++ is-valid
|= [bech=tape last-1-pos=@] ^- ?
?& ?|(=((cass bech) bech) =((cuss bech) bech)) :: to upper or to lower is same as bech
(gte last-1-pos 1)
(lte (add last-1-pos 7) (lent bech))
(lte (lent bech) 90)
(levy bech |=(c=@tD (gte c 33)))
(levy bech |=(c=@tD (lte c 126)))
==
:: data should be 5bit words
::
++ encode-raw
|= [hrp=tape data=(list @)]
^- cord
=/ combined=(list @)
(weld data (checksum hrp data))
%- crip
(zing ~[hrp "1" (tape (murn combined value-to-charset))])
++ decode-raw
|= body=cord
^- (unit raw-decoded)
=/ bech (cass (trip body)) :: to lowercase
=/ pos (flop (fand "1" bech))
?~ pos ~
=/ last-1=@ i.pos
?. (is-valid bech last-1) :: check bech32 validity (not segwit validity or checksum)
~
=/ hrp (scag last-1 bech)
=/ encoded-data-and-checksum=(list @)
(slag +(last-1) bech)
=/ data-and-checksum=(list @)
%+ murn encoded-data-and-checksum
charset-to-value
?. =((lent encoded-data-and-checksum) (lent data-and-checksum)) :: ensure all were in CHARSET
~
?. (verify-checksum hrp data-and-checksum)
~
=/ checksum-pos (sub (lent data-and-checksum) 6)
`[hrp (scag checksum-pos data-and-checksum) (slag checksum-pos data-and-checksum)]
:: +from-address: BIP173 bech32 address encoding to hex
:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki
:: expects to drop a leading 5-bit 0 (the witness version)
::
++ from-address
|= body=cord
^- hexb
~| "Invalid bech32 address"
=/ d=(unit raw-decoded) (decode-raw body)
?> ?=(^ d)
=/ bs=bits (from-atoms:bit 5 data.u.d)
=/ byt-len=@ (div (sub wid.bs 5) 8)
?> =(5^0b0 (take:bit 5 bs))
?> ?| =(20 byt-len)
=(32 byt-len)
==
[byt-len `@ux`dat:(take:bit (mul 8 byt-len) (drop:bit 5 bs))]
:: pubkey is the 33 byte ECC compressed public key
::
++ encode-pubkey
|= [=network pubkey=byts]
^- (unit cord)
?. =(33 wid.pubkey)
~|('pubkey must be a 33 byte ECC compressed public key' !!)
=/ prefix (~(get by prefixes) network)
?~ prefix ~
:- ~
%+ encode-raw u.prefix
[0v0 (to-atoms:bit 5 [160 `@ub`dat:(hash-160 pubkey)])]
--

1
pkg/arvo/lib/bip/b173.hoon Symbolic link
View File

@ -0,0 +1 @@
../../../base-dev/lib/bip/b173.hoon

View File

@ -1,182 +0,0 @@
:: BIP174: PSBTs
:: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki
::
/- sur=bitcoin
/+ bcu=bitcoin-utils
=, sur
=, bcu
|%
++ en
|%
++ globals
|= rawtx=hexb
^- map:psbt
:~ [[1 0x0] rawtx]
==
::
++ input
|= [only-witness=? i=in:psbt]
^- map:psbt
%+ weld
?: only-witness ~
~[[1^0x0 rawtx.i]]
:~ (witness-tx i)
(hdkey %input hdkey.i)
==
::
++ output
|= =out:psbt
^- map:psbt
?~ hk.out ~
:~ (hdkey %output u.hk.out)
==
::
++ witness-tx
|= i=in:psbt
^- keyval:psbt
:- [1 0x1]
%- cat:byt
:~ (flip:byt 8^value.utxo.i)
1^0x16
2^0x14
(hash-160 pubkey.hdkey.i)
==
::
++ hdkey
|= [=target:psbt h=^hdkey]
^- keyval:psbt
=/ typ=@ux
?- target
%input 0x6
%output 0x2
==
=/ coin-type=hexb
?- network.h
%main
1^0x0
%testnet
1^0x1
==
:- (cat:byt ~[1^typ pubkey.h])
%- cat:byt
:~ fprint.h
1^`@ux`bipt.h 3^0x80
coin-type 3^0x80
4^0x80
1^`@ux`chyg.h 3^0x0
(flip:byt 4^idx.h)
==
::
++ keyval-byts
|= kv=keyval:psbt
^- hexb
%- cat:byt
:~ 1^wid.key.kv
key.kv
1^wid.val.kv
val.kv
==
::
++ map-byts
|= m=map:psbt
^- (unit hexb)
?~ m ~
:- ~
%- cat:byt
(turn m keyval-byts)
--
++ base64
|= b=hexb
^- base64:psbt
%- en:base64:mimes:html
(flip:byt b)
:: +encode: make base64 cord of PSBT
:: - only-witness: don't include non-witness UTXO
::
++ encode
|= $: only-witness=?
rawtx=hexb
txid=hexb
inputs=(list in:psbt)
outputs=(list out:psbt)
==
^- base64:psbt
=/ sep=(unit hexb) `1^0x0
=/ final=(list (unit hexb))
%+ join sep
%+ turn
%- zing
:~ ~[(globals:en rawtx)]
(turn inputs (cury input:en only-witness))
(turn outputs output:en)
==
map-byts:en
%- base64:en
^- byts
%- cat:byt
%+ weld ~[[5 0x70.7362.74ff]]
(murn (snoc final sep) same)
::
++ parse
|= psbt-base64=cord
^- (list map:psbt)
=/ todo=hexb
(drop:byt 5 (to-byts psbt-base64))
=| acc=(list map:psbt)
=| m=map:psbt
|-
?: =(wid.todo 0)
(snoc acc m)
:: 0x0: map separator
::
?: =(1^0x0 (take:byt 1 todo))
$(acc (snoc acc m), m *map:psbt, todo (drop:byt 1 todo))
=^ kv todo (next-keyval todo)
$(m (snoc m kv))
:: +get-txid: extract txid from a valid PSBT
::
++ get-txid
|= psbt-base64=cord
^- hexb
=/ tx=hexb
%- raw-tx
%+ drop:byt 5
(to-byts psbt-base64)
%- flip:byt
(dsha256 tx)
:: +raw-tx: extract hex transaction
:: looks for key 0x0 in global map
:: crashes if tx not in hex
::
++ raw-tx
|= b=hexb
^- hexb
|-
?: =(wid.b 0) !!
?: =(1^0x0 (take:byt 1 b)) !!
=/ nk (next-keyval b)
?: =(0x0 dat.key.kv.nk)
val.kv.nk
$(b rest.nk)
:: +next-keyval: returns next key-val in a PSBT map
:: input first byte must be a map key length
::
++ next-keyval
|= b=hexb
^- [kv=keyval:psbt rest=hexb]
=/ klen dat:(take:byt 1 b)
=/ k (take:byt klen (drop:byt 1 b))
=/ vlen dat:(take:byt 1 (drop:byt (add 1 klen) b))
=/ v (take:byt vlen (drop:byt (add 2 klen) b))
?> ?&((gth wid.k 0) (gth wid.v 0))
:- [k v]
(drop:byt ;:(add 2 klen vlen) b)
::
++ to-byts
|= psbt-base64=cord
^- hexb
~| "Invalid PSBT"
=+ p=(de:base64:mimes:html psbt-base64)
?~ p !!
(flip:byt u.p)
--

1
pkg/arvo/lib/bip/b174.hoon Symbolic link
View File

@ -0,0 +1 @@
../../../base-dev/lib/bip/b174.hoon

View File

@ -1,243 +0,0 @@
:: bip32 implementation in hoon
::
:: to use, call one of the core initialization arms.
:: using the produced core, derive as needed and take out the data you want.
::
::NOTE tested to be correct against
:: https://en.bitcoin.it/wiki/BIP_0032_TestVectors
::
=, hmac:crypto
=, secp:crypto
=+ ecc=secp256k1
::
:: prv: private key
:: pub: public key
:: cad: chain code
:: dep: depth in chain
:: ind: index at depth
:: pif: parent fingerprint (4 bytes)
|_ [prv=@ pub=point.ecc cad=@ dep=@ud ind=@ud pif=@]
::
+$ keyc [key=@ cai=@] :: prv/pub key + chain code
::
:: elliptic curve operations and values
::
++ point priv-to-pub.ecc
::
++ ser-p compress-point.ecc
::
++ n n:t.ecc
::
:: core initialization
::
++ from-seed
|= byts
^+ +>
=+ der=(hmac-sha512l [12 'dees nioctiB'] [wid dat])
=+ pri=(cut 3 [32 32] der)
+>.$(prv pri, pub (point pri), cad (cut 3 [0 32] der))
::
++ from-private
|= keyc
+>(prv key, pub (point key), cad cai)
::
++ from-public
|= keyc
+>(pub (decompress-point.ecc key), cad cai)
::
++ from-public-point
|= [pon=point.ecc cai=@]
+>(pub pon, cad cai)
::
++ from-extended
|= t=tape
=+ x=(de-base58check 4 t)
=> |%
++ take
|= b=@ud
^- [v=@ x=@]
:- (end [3 b] x)
(rsh [3 b] x)
--
=^ k x (take 33)
=^ c x (take 32)
=^ i x (take 4)
=^ p x (take 4)
=^ d x (take 1)
?> =(0 x) :: sanity check
%. [d i p]
=< set-metadata
=+ v=(swag [1 3] t)
?: =("prv" v) (from-private k c)
?: =("pub" v) (from-public k c)
!!
::
++ set-metadata
|= [d=@ud i=@ud p=@]
+>(dep d, ind i, pif p)
::
:: derivation
::
++ derivation-path
;~ pfix
;~(pose (jest 'm/') (easy ~))
%+ most fas
;~ pose
%+ cook
|=(i=@ (add i (bex 31)))
;~(sfix dem soq)
::
dem
== ==
::
++ derive-path
|= t=tape
%- derive-sequence
(scan t derivation-path)
::
++ derive-sequence
|= j=(list @u)
?~ j +>
=. +> (derive i.j)
$(j t.j)
::
++ derive
?: =(0 prv)
derive-public
derive-private
::
++ derive-private
|= i=@u
^+ +>
:: we must have a private key to derive the next one
?: =(0 prv)
~| %know-no-private-key
!!
:: derive child at i
=/ [left=@ right=@]
=- [(cut 3 [32 32] -) (cut 3 [0 32] -)]
%+ hmac-sha512l [32 cad]
:- 37
?: (gte i (bex 31))
:: hardened child
(can 3 ~[4^i 32^prv 1^0])
:: normal child
(can 3 ~[4^i 33^(ser-p (point prv))])
=+ key=(mod (add left prv) n)
:: rare exception, invalid key, go to the next one
?: |(=(0 key) (gte left n)) $(i +(i))
%_ +>.$
prv key
pub (point key)
cad right
dep +(dep)
ind i
pif fingerprint
==
::
++ derive-public
|= i=@u
^+ +>
:: public keys can't be hardened
?: (gte i (bex 31))
~| %cant-derive-hardened-public-key
!!
:: derive child at i
=/ [left=@ right=@]
=- [(cut 3 [32 32] -) (cut 3 [0 32] -)]
%+ hmac-sha512l [32 cad]
37^(can 3 ~[4^i 33^(ser-p pub)])
:: rare exception, invalid key, go to the next one
?: (gte left n) $(i +(i)) ::TODO or child key is "point at infinity"
%_ +>.$
pub (add-points.ecc (point left) pub)
cad right
dep +(dep)
ind i
pif fingerprint
==
::
:: rendering
::
++ private-key ?.(=(0 prv) prv ~|(%know-no-private-key !!))
++ public-key (ser-p pub)
++ chain-code cad
++ private-chain [private-key cad]
++ public-chain [public-key cad]
::
++ identity (hash160 public-key)
++ fingerprint (cut 3 [16 4] identity)
::
++ address
|= network=?(%main %regtest %testnet)
^- @uc
:: removes checksum
::
%+ rsh [3 4]
%+ en-base58check
[4 (version-bytes network %pub %.n)]
[20 identity]
::
++ prv-extended
|= network=?(%main %regtest %testnet)
%+ en-b58c-bip32 (version-bytes network %prv %.y)
(build-extended private-key)
::
++ pub-extended
|= network=?(%main %regtest %testnet)
%+ en-b58c-bip32 (version-bytes network %pub %.y)
(build-extended public-key)
::
++ build-extended
|= key=@
%+ can 3
:~ 33^key
32^cad
4^ind
4^pif
1^dep
==
::
++ en-b58c-bip32
|= [v=@ k=@]
%- en-base58:mimes:html
(en-base58check [4 v] [74 k])
::
:: base58check
::
++ en-base58check
:: v: version bytes
:: d: data
|= [v=byts d=byts]
=+ p=[(add wid.v wid.d) (can 3 ~[d v])]
=- (can 3 ~[4^- p])
%+ rsh [3 28]
(sha-256l:sha 32 (sha-256l:sha p))
::
++ de-base58check
:: vw: amount of version bytes
|= [vw=@u t=tape]
=+ x=(de-base58:mimes:html t)
=+ hash=(sha-256l:sha 32 (sha-256:sha (rsh [3 4] x)))
?> =((end [3 4] x) (rsh [3 28] hash))
(cut 3 [vw (sub (met 3 x) (add 4 vw))] x)
::
++ hash160
|= d=@
(ripemd-160:ripemd:crypto 32 (sha-256:sha d))
::
++ version-bytes
|= [network=?(%main %regtest %testnet) type=?(%pub %prv) bip32=?]
^- @ux
|^
?- type
%pub ?:(bip32 xpub-key pay-to-pubkey)
%prv ?:(bip32 xprv-key private-key)
==
::
++ pay-to-pubkey ?:(=(network %main) 0x0 0x6f)
++ private-key ?:(=(network %main) 0x80 0xef)
++ xpub-key ?:(=(network %main) 0x488.b21e 0x435.87cf)
++ xprv-key ?:(=(network %main) 0x488.ade4 0x435.8394)
--
--

1
pkg/arvo/lib/bip32.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/bip32.hoon

View File

@ -1,46 +0,0 @@
:: bip39 implementation in hoon
::
/+ bip39-english
::
|%
++ from-entropy
|= byts
^- tape
=. wid (mul wid 8)
~| [%unsupported-entropy-bit-length wid]
?> &((gte wid 128) (lte wid 256))
::
=+ cs=(div wid 32)
=/ check=@
%+ rsh [0 (sub 256 cs)]
(sha-256l:sha (div wid 8) dat)
=/ bits=byts
:- (add wid cs)
%+ can 0
:~ cs^check
wid^dat
==
::
=/ pieces
|- ^- (list @)
:- (end [0 11] dat.bits)
?: (lte wid.bits 11) ~
$(bits [(sub wid.bits 11) (rsh [0 11] dat.bits)])
::
=/ words=(list tape)
%+ turn pieces
|= ind=@ud
(snag ind `(list tape)`bip39-english)
::
%+ roll (flop words)
|= [nex=tape all=tape]
?~ all nex
:(weld all " " nex)
::
::NOTE always produces a 512-bit result
++ to-seed
|= [mnem=tape pass=tape]
^- @
%- hmac-sha512t:pbkdf:crypto
[(crip mnem) (crip (weld "mnemonic" pass)) 2.048 64]
--

1
pkg/arvo/lib/bip39.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/bip39.hoon

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
../../../base-dev/lib/bip39/english.hoon

View File

@ -1,176 +0,0 @@
:: lib/bitcoin-utils.hoon
:: Utilities for working with BTC data types and transactions
::
/- *bitcoin
~% %bitcoin-utils-lib ..part ~
|%
::
:: TODO: move this bit/byt stuff to zuse
:: bit/byte utilities
::
::
:: +blop: munge bit and byt sequences (cat, flip, take, drop)
::
++ blop
~/ %blop
|_ =bloq
+$ biyts [wid=@ud dat=@]
++ cat
|= bs=(list biyts)
^- biyts
:- (roll (turn bs |=(b=biyts -.b)) add)
(can bloq (flop bs))
:: +flip: flip endianness while preserving lead/trail zeroes
::
++ flip
|= b=biyts
^- biyts
[wid.b (rev bloq b)]
:: +take: take n bloqs from front
:: pads front with extra zeroes if n is longer than input
::
++ take
|= [n=@ b=biyts]
^- biyts
?: (gth n wid.b)
[n dat.b]
[n (rsh [bloq (sub wid.b n)] dat.b)]
:: +drop: drop n bloqs from front
:: returns 0^0 if n >= width
::
++ drop
|= [n=@ b=biyts]
^- biyts
?: (gte n wid.b)
0^0x0
=+ n-take=(sub wid.b n)
[n-take (end [bloq n-take] dat.b)]
--
++ byt ~(. blop 3)
::
++ bit
~/ %bit
=/ bl ~(. blop 0)
|%
++ cat cat:bl:bit
++ flip flip:bl:bit
++ take take:bl:bit
++ drop drop:bl:bit
++ from-atoms
|= [bitwidth=@ digits=(list @)]
^- bits
%- cat:bit
%+ turn digits
|= a=@
?> (lte (met 0 a) bitwidth)
[bitwidth `@ub`a]
:: +to-atoms: convert bits to atoms of bitwidth
::
++ to-atoms
|= [bitwidth=@ bs=bits]
^- (list @)
=| res=(list @)
?> =(0 (mod wid.bs bitwidth))
|-
?: =(0 wid.bs) res
%= $
res (snoc res dat:(take:bit bitwidth bs))
bs (drop:bit bitwidth bs)
==
--
:: big endian sha256: input and output are both MSB first (big endian)
::
++ sha256
~/ %sha256
|= =byts
^- hexb
%- flip:byt
[32 (shay (flip:byt byts))]
::
++ dsha256
~/ %dsha256
|= =byts
(sha256 (sha256 byts))
::
++ hash-160
~/ %hash-160
|= val=byts
^- hexb
=, ripemd:crypto
:- 20
%- ripemd-160
(sha256 val)
::
:: hxb: hex parsing utilities
::
++ hxb
~% %hxb ..blop ~
|%
++ from-cord
~/ %from-cord
|= h=@t
^- hexb
?: =('' h) 1^0x0
:: Add leading 00
::
=+ (lsh [3 2] h)
:: Group by 4-size block
::
=+ (rsh [3 2] -)
:: Parse hex to atom
::
=/ a (need (de:base16:mimes:html -))
[-.a `@ux`+.a]
::
++ to-cord
~/ %to-cord
|= =hexb
^- cord
(en:base16:mimes:html hexb)
--
::
:: +csiz: CompactSize integers (a Bitcoin-specific datatype)
:: https://btcinformation.org/en/developer-reference#compactsize-unsigned-integers
:: - encode: big endian to little endian
:: - decode: little endian to big endian
::
++ csiz
~% %csiz ..blop ~
|%
++ en
~/ %en
|= a=@
^- hexb
=/ l=@ (met 3 a)
?: =(l 1) 1^a
?: =(l 2) (cat:byt ~[1^0xfd (flip:byt 2^a)])
?: (lte l 4) (cat:byt ~[1^0xfe (flip:byt 4^a)])
?: (lte l 8) (cat:byt ~[1^0xff (flip:byt 8^a)])
~|("Cannot encode CompactSize longer than 8 bytes" !!)
::
++ de
~/ %de
|= h=hexb
^- [n=hexb rest=hexb]
=/ s=@ux dat:(take:byt 1 h)
?: (lth s 0xfd) [1^s (drop:byt 1 h)]
~| "Invalid compact-size at start of {<h>}"
=/ len=bloq
?+ s !!
%0xfd 1
%0xfe 2
%0xff 3
==
:_ (drop:byt (add 1 len) h)
%- flip:byt
(take:byt (bex len) (drop:byt 1 h))
:: +dea: atom instead of hexb for parsed CompactSize
::
++ dea
|= h=hexb
^- [a=@ rest=hexb]
=> (de h)
[dat.n rest]
--
--

View File

@ -0,0 +1 @@
../../base-dev/lib/bitcoin-utils.hoon

View File

@ -1,61 +0,0 @@
|%
++ static :: freeze .mdh hoon subset
|= gen=hoon ^- [inf=(map term dime) elm=manx]
?+ -.gen
=/ gen ~(open ap gen)
?: =(gen ^gen) ~|([%cram-dynamic -.gen] !!)
$(gen gen)
::
%xray [~ (single (shut gen))]
^ [(malt (frontmatter p.gen)) (single (shut q.gen))]
==
::
++ single :: unwrap one-elem marl
|= xml=marl ^- manx
?: ?=([* ~] xml) i.xml
~|(%many-elems !!)
::
++ shut-mart :: xml attrs
|=([n=mane v=(list beer:hoot)] [n (turn v |=(a=beer:hoot ?^(a !! a)))])
::
++ shut :: as xml constant
|= gen=hoon ^- marl
?+ -.gen ~|([%bad-xml -.gen] !!)
%dbug $(gen q.gen)
::
%xray
[[n.g.p.gen (turn a.g.p.gen shut-mart)] $(gen [%mcts c.p.gen])]~
::
%mcts
?~ p.gen ~
=- (weld - $(p.gen t.p.gen))
?^ -.i.p.gen $(gen [%xray i.p.gen])
~| [%shut-tuna -.i.p.gen]
?+ -.i.p.gen !!
%manx ?>(?=(%xray -.p.i.p.gen) $(gen p.i.p.gen))
%marl ?>(?=(%mcts -.p.i.p.gen) $(gen p.i.p.gen))
==
==
::
::
++ frontmatter :: parse ~[[%foo 1] [%bar ~s2]]
|= gen=hoon ^- (list [term dime])
?: ?=([%bust %null] gen) ~
?: ?=(%dbug -.gen) $(gen q.gen)
?. ?=(%clsg -.gen) ~|([%bad-frontmatter -.gen] !!)
%+ turn p.gen
|= gen=hoon
?. ?=(^ -.gen)
=/ gen ~(open ap gen)
?: =(gen ^gen) ~|([%bad-frontmatter-elem -.gen] !!)
$(gen gen)
=/ hed (as-dime p.gen)
?. =(%tas p.hed) ~|([%bad-frontmatter-key-type p.hed] !!)
[q.hed (as-dime q.gen)]
::
++ as-dime :: %foo ~.foo 0vbar etc
|= gen=hoon ^- dime
?: ?=(%dbug -.gen) $(gen q.gen)
?. ?=([?(%rock %sand) @ @] gen) ~|([%bad-literal gen] !!)
+.gen
--

1
pkg/arvo/lib/cram.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/cram.hoon

View File

@ -351,6 +351,6 @@
++ note-write-csv-to-clay
|= [pax=path file-content=wain]
?> =(%csv (snag (dec (lent pax)) pax))
[%c [%info %home %& [pax %ins %csv !>(file-content)]~]]
[%c [%info %base %& [pax %ins %csv !>(file-content)]~]]
::
--

View File

@ -1,155 +0,0 @@
:: dbug: agent wrapper for generic debugging tools
::
:: usage: %-(agent:dbug your-agent)
::
|%
+$ poke
$% [%bowl ~]
[%state grab=cord]
[%incoming =about]
[%outgoing =about]
==
::
+$ about
$@ ~
$% [%ship =ship]
[%path =path]
[%wire =wire]
[%term =term]
==
::
++ agent
|= =agent:gall
^- agent:gall
!.
|_ =bowl:gall
+* this .
ag ~(. agent bowl)
::
++ on-poke
|= [=mark =vase]
^- (quip card:agent:gall agent:gall)
?. ?=(%dbug mark)
=^ cards agent (on-poke:ag mark vase)
[cards this]
=/ dbug
!<(poke vase)
=; =tang
((%*(. slog pri 1) tang) [~ this])
?- -.dbug
%bowl [(sell !>(bowl))]~
::
%state
=? grab.dbug =('' grab.dbug) '-'
=; product=^vase
[(sell product)]~
=/ state=^vase
:: if the underlying app has implemented a /dbug/state scry endpoint,
:: use that vase in place of +on-save's.
::
=/ result=(each ^vase tang)
(mule |.(q:(need (need (on-peek:ag /x/dbug/state)))))
?:(?=(%& -.result) p.result on-save:ag)
%+ slap
(slop state !>([bowl=bowl ..zuse]))
(ream grab.dbug)
::
%incoming
=; =tang
?^ tang tang
[%leaf "no matching subscriptions"]~
%+ murn
%+ sort ~(tap by sup.bowl)
|= [[* a=[=ship =path]] [* b=[=ship =path]]]
(aor [path ship]:a [path ship]:b)
|= [=duct [=ship =path]]
^- (unit tank)
=; relevant=?
?. relevant ~
`>[path=path from=ship duct=duct]<
?: ?=(~ about.dbug) &
?- -.about.dbug
%ship =(ship ship.about.dbug)
%path ?=(^ (find path.about.dbug path))
%wire %+ lien duct
|=(=wire ?=(^ (find wire.about.dbug wire)))
%term !!
==
::
%outgoing
=; =tang
?^ tang tang
[%leaf "no matching subscriptions"]~
%+ murn
%+ sort ~(tap by wex.bowl)
|= [[[a=wire *] *] [[b=wire *] *]]
(aor a b)
|= [[=wire =ship =term] [acked=? =path]]
^- (unit tank)
=; relevant=?
?. relevant ~
`>[wire=wire agnt=[ship term] path=path ackd=acked]<
?: ?=(~ about.dbug) &
?- -.about.dbug
%ship =(ship ship.about.dbug)
%path ?=(^ (find path.about.dbug path))
%wire ?=(^ (find wire.about.dbug wire))
%term =(term term.about.dbug)
==
==
::
++ on-peek
|= =path
^- (unit (unit cage))
?. ?=([@ %dbug *] path)
(on-peek:ag path)
?+ path [~ ~]
[%u %dbug ~] ``noun+!>(&)
[%x %dbug %state ~] ``noun+!>(on-save:ag)
[%x %dbug %subscriptions ~] ``noun+!>([wex sup]:bowl)
==
::
++ on-init
^- (quip card:agent:gall agent:gall)
=^ cards agent on-init:ag
[cards this]
::
++ on-save on-save:ag
::
++ on-load
|= old-state=vase
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-load:ag old-state)
[cards this]
::
++ on-watch
|= =path
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-watch:ag path)
[cards this]
::
++ on-leave
|= =path
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-leave:ag path)
[cards this]
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-agent:ag wire sign)
[cards this]
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-arvo:ag wire sign-arvo)
[cards this]
::
++ on-fail
|= [=term =tang]
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-fail:ag term tang)
[cards this]
--
--

1
pkg/arvo/lib/dbug.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/dbug.hoon

View File

@ -1,69 +0,0 @@
/+ skeleton
|* [agent=* help=*]
?: ?=(%& help)
~| %default-agent-helpfully-crashing
skeleton
|_ =bowl:gall
++ on-init
`agent
::
++ on-save
!>(~)
::
++ on-load
|= old-state=vase
`agent
::
++ on-poke
|= =cage
~| "unexpected poke to {<dap.bowl>} with mark {<p.cage>}"
!!
::
++ on-watch
|= =path
~| "unexpected subscription to {<dap.bowl>} on path {<path>}"
!!
::
++ on-leave
|= path
`agent
::
++ on-peek
|= =path
~| "unexpected scry into {<dap.bowl>} on path {<path>}"
!!
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card:agent:gall _agent)
?- -.sign
%poke-ack
?~ p.sign
`agent
%- (slog leaf+"poke failed from {<dap.bowl>} on wire {<wire>}" u.p.sign)
`agent
::
%watch-ack
?~ p.sign
`agent
=/ =tank leaf+"subscribe failed from {<dap.bowl>} on wire {<wire>}"
%- (slog tank u.p.sign)
`agent
::
%kick `agent
%fact
~| "unexpected subscription update to {<dap.bowl>} on wire {<wire>}"
~| "with mark {<p.cage.sign>}"
!!
==
::
++ on-arvo
|= [=wire =sign-arvo]
~| "unexpected system response {<-.sign-arvo>} to {<dap.bowl>} on wire {<wire>}"
!!
::
++ on-fail
|= [=term =tang]
%- (slog leaf+"error in {<dap.bowl>}" >term< tang)
`agent
--

View File

@ -0,0 +1 @@
../../base-dev/lib/default-agent.hoon

View File

@ -1,210 +0,0 @@
/- asn1
:: |der: distinguished encoding rules for ASN.1
::
:: DER is a tag-length-value binary encoding for ASN.1, designed
:: so that there is only one (distinguished) valid encoding for an
:: instance of a type.
::
|%
:: +en:der: encode +spec:asn1 to +octs (kindof)
::
++ en
=< |= a=spec:asn1
^- [len=@ud dat=@ux]
=/ b ~(ren raw a)
[(lent b) (rep 3 b)]
|%
:: +raw:en:der: door for encoding +spec:asn1 to list of bytes
::
++ raw
|_ pec=spec:asn1
:: +ren:raw:en:der: render +spec:asn1 to tag-length-value bytes
::
++ ren
^- (list @D)
=/ a lem
[tag (weld (len a) a)]
:: +tag:raw:en:der: tag byte
::
++ tag
^- @D
?- pec
[%int *] 2
[%bit *] 3
[%oct *] 4
[%nul *] 5
[%obj *] 6
[%seq *] 48 :: constructed: (con 0x20 16)
[%set *] 49 :: constructed: (con 0x20 17)
[%con *] ;: con
0x80 :: context-specifc
?:(imp.bes.pec 0 0x20) :: implicit?
(dis 0x1f tag.bes.pec) :: 5 bits of custom tag
==
==
:: +lem:raw:en:der: element bytes
::
++ lem
^- (list @D)
?- pec
:: unsigned only, interpreted as positive-signed and
:: rendered in big-endian byte order. negative-signed would
:: be two's complement
::
[%int *] =/ a (flop (rip 3 int.pec))
?~ a [0 ~]
?:((lte i.a 127) a [0 a])
:: padded to byte-width, must be already byte-aligned
::
[%bit *] =/ a (rip 3 bit.pec)
=/ b ~| %der-invalid-bit
?. =(0 (mod len.pec 8))
~|(%der-invalid-bit-alignment !!)
(sub (div len.pec 8) (lent a))
[0 (weld a (reap b 0))]
:: padded to byte-width
::
[%oct *] =/ a (rip 3 oct.pec)
=/ b ~| %der-invalid-oct
(sub len.pec (lent a))
(weld a (reap b 0))
::
[%nul *] ~
[%obj *] (rip 3 obj.pec)
::
[%seq *] %- zing
|- ^- (list (list @))
?~ seq.pec ~
:- ren(pec i.seq.pec)
$(seq.pec t.seq.pec)
:: presumed to be already deduplicated and sorted
::
[%set *] %- zing
|- ^- (list (list @))
?~ set.pec ~
:- ren(pec i.set.pec)
$(set.pec t.set.pec)
:: already constructed
::
[%con *] con.pec
==
:: +len:raw:en:der: length bytes
::
++ len
|= a=(list @D)
^- (list @D)
=/ b (lent a)
?: (lte b 127)
[b ~] :: note: big-endian
[(con 0x80 (met 3 b)) (flop (rip 3 b))]
--
--
:: +de:der: decode atom to +spec:asn1
::
++ de
|= [len=@ud dat=@ux]
^- (unit spec:asn1)
:: XX refactor into +parse
=/ a (rip 3 dat)
=/ b ~| %der-invalid-len
(sub len (lent a))
(rust `(list @D)`(weld a (reap b 0)) parse)
:: +parse:der: DER parser combinator
::
++ parse
=< ^- $-(nail (like spec:asn1))
;~ pose
(stag %int (bass 256 (sear int ;~(pfix (tag 2) till))))
(stag %bit (sear bit (boss 256 ;~(pfix (tag 3) till))))
(stag %oct (boss 256 ;~(pfix (tag 4) till)))
(stag %nul (cold ~ ;~(plug (tag 5) (tag 0))))
(stag %obj (^boss 256 ;~(pfix (tag 6) till)))
(stag %seq (sear recur ;~(pfix (tag 48) till)))
(stag %set (sear recur ;~(pfix (tag 49) till)))
(stag %con ;~(plug (sear context next) till))
==
|%
:: +tag:parse:der: parse tag byte
::
++ tag
|=(a=@D (just a))
:: +int:parse:der: sear unsigned big-endian bytes
::
++ int
|= a=(list @D)
^- (unit (list @D))
?~ a ~
?: ?=([@ ~] a) `a
?. =(0 i.a) `a
?.((gth i.t.a 127) ~ `t.a)
:: +bit:parse:der: convert bytewidth to bitwidth
::
++ bit
|= [len=@ud dat=@ux]
^- (unit [len=@ud dat=@ux])
?. =(0 (end 3 dat)) ~
:+ ~
(mul 8 (dec len))
(rsh 3 dat)
:: +recur:parse:der: parse bytes for a list of +spec:asn1
::
++ recur
|=(a=(list @) (rust a (star parse)))
:: +context:parse:der: decode context-specific tag byte
::
++ context
|= a=@D
^- (unit bespoke:asn1)
?. =(1 (cut 0 [7 1] a)) ~
:+ ~
=(1 (cut 0 [5 1] a))
(dis 0x1f a)
:: +boss:parse:der: shadowed to count as well
::
:: Use for parsing +octs more broadly?
::
++ boss
|* [wuc=@ tyd=rule]
%+ cook
|= waq=(list @)
:- (lent waq)
(reel waq |=([p=@ q=@] (add p (mul wuc q))))
tyd
:: +till:parse:der: parser combinator for len-prefixed bytes
::
:: advance until
::
++ till
|= tub=nail
^- (like (list @D))
?~ q.tub
(fail tub)
:: fuz: first byte - length, or length of the length
::
=* fuz i.q.tub
:: nex: offset of value bytes from fuz
:: len: length of value bytes
::
=/ [nex=@ len=@]
:: faz: meaningful bits in fuz
::
=/ faz (end [0 7] fuz)
?: =(0 (cut 0 [7 1] fuz))
[0 faz]
[faz (rep 3 (flop (scag faz t.q.tub)))]
?: ?& !=(0 nex)
!=(nex (met 3 len))
==
(fail tub)
:: zuf: value bytes
::
=/ zuf (swag [nex len] t.q.tub)
?. =(len (lent zuf))
(fail tub)
:: zaf: product nail
::
=/ zaf [p.p.tub (add +(nex) q.p.tub)]
[zaf `[zuf zaf (slag (add nex len) t.q.tub)]]
--
--

1
pkg/arvo/lib/der.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/der.hoon

View File

@ -0,0 +1,32 @@
=, clay
|%
++ jam-desk
|= [our=ship =desk now=@da]
~> %slog.0^leaf/"jamming desk {<desk>}"
%- jam
%- ?:(=(%base desk) remove-misc-dirs same)
%- ankh-to-map
=< ank
.^(dome:clay %cv /(scot %p our)/[desk]/(scot %da now))
::
++ remove-misc-dirs
|= fiz=(map path page)
^- (map path page)
%- ~(gas by *(map path page))
%+ skip ~(tap by fiz)
|= [p=path *]
?| ?=([%tmp *] p)
?=([%tests *] p)
==
::
++ ankh-to-map
=| res=(map path page)
=| pax=path
|= a=ankh
^- (map path page)
=? res ?=(^ fil.a) (~(put by res) pax [p q.q]:q.u.fil.a)
=/ dir=(list [seg=@ta =ankh]) ~(tap by dir.a)
|- ^+ res
?~ dir res
$(dir t.dir, res ^$(pax (snoc pax seg.i.dir), a ankh.i.dir))
--

View File

@ -1,910 +0,0 @@
:: ethereum: utilities
::
=, ethereum-types
|%
:: deriving and using ethereum keys
::
++ key
|%
++ address-from-pub
=, keccak:crypto
|= pub=@
%+ end [3 20]
%+ keccak-256 64
(rev 3 64 pub)
::
++ address-from-prv
(cork pub-from-prv address-from-pub)
::
++ pub-from-prv
=, secp256k1:secp:crypto
|= prv=@
%- serialize-point
(priv-to-pub prv)
::
++ sign-transaction
=, crypto
|= [tx=transaction:rpc pk=@]
^- @ux
:: hash the raw transaction data
=/ hash=@
=/ dat=@
%- encode-atoms:rlp
:: with v=chain-id, r=0, s=0
tx(chain-id [chain-id.tx 0 0 ~])
=+ wid=(met 3 dat)
%- keccak-256:keccak
[wid (rev 3 wid dat)]
:: sign transaction hash with private key
=+ (ecdsa-raw-sign:secp256k1:secp hash pk)
:: complete transaction is raw data, with r and s
:: taken from the signature, and v as per eip-155
%- encode-atoms:rlp
tx(chain-id [:(add (mul chain-id.tx 2) 35 v) r s ~])
--
::
:: rlp en/decoding
::NOTE https://github.com/ethereum/wiki/wiki/RLP
::
++ rlp
|%
::NOTE rlp encoding doesn't really care about leading zeroes,
:: but because we need to disinguish between no-bytes zero
:: and one-byte zero (and also empty list) we end up with
:: this awful type...
+$ item
$% [%l l=(list item)]
[%b b=byts]
==
:: +encode-atoms: encode list of atoms as a %l of %b items
::
++ encode-atoms
|= l=(list @)
^- @
%+ encode %l
%+ turn l
|=(a=@ b+[(met 3 a) a])
::
++ encode
|= in=item
|^ ^- @
?- -.in
%b
?: &(=(1 wid.b.in) (lte dat.b.in 0x7f))
dat.b.in
=- (can 3 ~[b.in [(met 3 -) -]])
(encode-length wid.b.in 0x80)
::
%l
=/ out=@
%+ roll l.in
|= [ni=item en=@]
(cat 3 (encode ni) en)
%^ cat 3 out
(encode-length (met 3 out) 0xc0)
==
::
++ encode-length
|= [len=@ off=@]
?: (lth len 56) (add len off)
=- (cat 3 len -)
:(add (met 3 len) off 55)
--
:: +decode-atoms: decode expecting a %l of %b items, producing atoms within
::
++ decode-atoms
|= dat=@
^- (list @)
=/ i=item (decode dat)
~| [%unexpected-data i]
?> ?=(%l -.i)
%+ turn l.i
|= i=item
~| [%unexpected-list i]
?> ?=(%b -.i)
dat.b.i
::
++ decode
|= dat=@
^- item
=/ bytes=(list @) (flop (rip 3 dat))
=? bytes ?=(~ bytes) ~[0]
|^ item:decode-head
::
++ decode-head
^- [done=@ud =item]
?~ bytes
~| %rlp-unexpected-end
!!
=* byt i.bytes
:: byte in 0x00-0x79 range encodes itself
::
?: (lte byt 0x79)
:- 1
[%b 1^byt]
:: byte in 0x80-0xb7 range encodes string length
::
?: (lte byt 0xb7)
=+ len=(sub byt 0x80)
:- +(len)
:- %b
len^(get-value 1 len)
:: byte in 0xb8-0xbf range encodes string length length
::
?: (lte byt 0xbf)
=+ led=(sub byt 0xb7)
=+ len=(get-value 1 led)
:- (add +(led) len)
:- %b
len^(get-value +(led) len)
:: byte in 0xc0-f7 range encodes list length
::
?: (lte byt 0xf7)
=+ len=(sub byt 0xc0)
:- +(len)
:- %l
%. len
decode-list(bytes (slag 1 `(list @)`bytes))
:: byte in 0xf8-ff range encodes list length length
::
?: (lte byt 0xff)
=+ led=(sub byt 0xf7)
=+ len=(get-value 1 led)
:- (add +(led) len)
:- %l
%. len
decode-list(bytes (slag +(led) `(list @)`bytes))
~| [%rip-not-bloq-3 `@ux`byt]
!!
::
++ decode-list
|= rem=@ud
^- (list item)
?: =(0 rem) ~
=+ ^- [don=@ud =item] ::TODO =/
decode-head
:- item
%= $
rem (sub rem don)
bytes (slag don bytes)
==
::
++ get-value
|= [at=@ud to=@ud]
^- @
(rep 3 (flop (swag [at to] bytes)))
--
--
::
:: abi en/decoding
::NOTE https://solidity.readthedocs.io/en/develop/abi-spec.html
::
++ abi
=> |%
:: solidity types. integer bitsizes ignored
++ etyp
$@ $? :: static
%address %bool
%int %uint
%real %ureal
:: dynamic
%bytes %string
==
$% :: static
[%bytes-n n=@ud]
:: dynamic
[%array-n t=etyp n=@ud]
[%array t=etyp]
==
::
:: solidity-style typed data. integer bitsizes ignored
++ data
$% [%address p=address]
[%string p=tape]
[%bool p=?]
[%int p=@sd]
[%uint p=@ud]
[%real p=@rs]
[%ureal p=@urs]
[%array-n p=(list data)]
[%array p=(list data)]
[%bytes-n p=octs] ::TODO just @, because context knows length?
[%bytes p=octs]
==
--
=, mimes:html
|%
:: encoding
::
++ encode-args
:: encode list of arguments.
::
|= das=(list data)
^- tape
(encode-data [%array-n das])
::
++ encode-data
:: encode typed data into ABI bytestring.
::
|= dat=data
^- tape
?+ -.dat
~| [%unsupported-type -.dat]
!!
::
%array-n
:: enc(X) = head(X[0]) ... head(X[k-1]) tail(X[0]) ... tail(X[k-1])
:: where head and tail are defined for X[i] being of a static type as
:: head(X[i]) = enc(X[i]) and tail(X[i]) = "" (the empty string), or as
:: head(X[i]) = enc(len( head(X[0])..head(X[k-1])
:: tail(X[0])..tail(X[i-1]) ))
:: and tail(X[i]) = enc(X[i]) otherwise.
::
:: so: if it's a static type, data goes in the head. if it's a dynamic
:: type, a reference goes into the head and data goes into the tail.
::
:: in the head, we first put a placeholder where references need to go.
=+ hol=(reap 64 'x')
=/ hes=(list tape)
%+ turn p.dat
|= d=data
?. (is-dynamic-type d) ^$(dat d)
hol
=/ tas=(list tape)
%+ turn p.dat
|= d=data
?. (is-dynamic-type d) ""
^$(dat d)
:: once we know the head and tail, we can fill in the references in head.
=- (weld nes `tape`(zing tas))
^- [@ud nes=tape]
=+ led=(lent (zing hes))
%+ roll hes
|= [t=tape i=@ud nes=tape]
:- +(i)
:: if no reference needed, just put the data.
?. =(t hol) (weld nes t)
:: calculate byte offset of data we need to reference.
=/ ofs=@ud
=- (div - 2) :: two hex digits per byte.
%+ add led :: count head, and
%- lent %- zing :: count all tail data
(scag i tas) :: preceding ours.
=+ ref=^$(dat [%uint ofs])
:: shouldn't hit this unless we're sending over 2gb of data?
~| [%weird-ref-lent (lent ref)]
?> =((lent ref) (lent hol))
(weld nes ref)
::
%array :: where X has k elements (k is assumed to be of type uint256):
:: enc(X) = enc(k) enc([X[1], ..., X[k]])
:: i.e. it is encoded as if it were an array of static size k, prefixed
:: with the number of elements.
%+ weld $(dat [%uint (lent p.dat)])
$(dat [%array-n p.dat])
::
%bytes-n
:: enc(X) is the sequence of bytes in X padded with zero-bytes to a
:: length of 32.
:: Note that for any X, len(enc(X)) is a multiple of 32.
~| [%bytes-n-too-long max=32 actual=p.p.dat]
?> (lte p.p.dat 32)
(pad-to-multiple (render-hex-bytes p.dat) 64 %right)
::
%bytes :: of length k (which is assumed to be of type uint256)
:: enc(X) = enc(k) pad_right(X), i.e. the number of bytes is encoded as a
:: uint256 followed by the actual value of X as a byte sequence, followed
:: by the minimum number of zero-bytes such that len(enc(X)) is a
:: multiple of 32.
%+ weld $(dat [%uint p.p.dat])
(pad-to-multiple (render-hex-bytes p.dat) 64 %right)
::
%string
:: enc(X) = enc(enc_utf8(X)), i.e. X is utf-8 encoded and this value is
:: interpreted as of bytes type and encoded further. Note that the length
:: used in this subsequent encoding is the number of bytes of the utf-8
:: encoded string, not its number of characters.
$(dat [%bytes (lent p.dat) (swp 3 (crip p.dat))])
::
%uint
:: enc(X) is the big-endian encoding of X, padded on the higher-order
:: (left) side with zero-bytes such that the length is a multiple of 32
:: bytes.
(pad-to-multiple (render-hex-bytes (as-octs p.dat)) 64 %left)
::
%bool
:: as in the uint8 case, where 1 is used for true and 0 for false
$(dat [%uint ?:(p.dat 1 0)])
::
%address
:: as in the uint160 case
$(dat [%uint `@ud`p.dat])
==
::
++ is-dynamic-type
|= a=data
?. ?=(%array-n -.a)
?=(?(%string %bytes %array) -.a)
&(!=((lent p.a) 0) (lien p.a is-dynamic-type))
::
:: decoding
::
++ decode-topics decode-arguments
::
++ decode-results
:: rex: string of hex bytes with leading 0x.
|* [rex=@t tys=(list etyp)]
=- (decode-arguments - tys)
%^ rut 9
(rsh [3 2] rex)
(curr rash hex)
::
++ decode-arguments
|* [wos=(list @) tys=(list etyp)]
=/ wos=(list @) wos :: get rid of tmi
=| win=@ud
=< (decode-from 0 tys)
|%
++ decode-from
|* [win=@ud tys=(list etyp)]
?~ tys !!
=- ?~ t.tys dat
[dat $(win nin, tys t.tys)]
(decode-one win ~[i.tys])
::
++ decode-one
::NOTE we take (list etyp) even though we only operate on
:: a single etyp as a workaround for urbit/arvo#673
|* [win=@ud tys=(list etyp)]
=- [nin dat]=- ::NOTE ^= regular form broken
?~ tys !!
=* typ i.tys
=+ wor=(snag win wos)
?+ typ
~| [%unsupported-type typ]
!!
::
?(%address %bool %uint) :: %int %real %ureal
:- +(win)
?- typ
%address `@ux`wor
%uint `@ud`wor
%bool =(1 wor)
==
::
%string
=+ $(tys ~[%bytes])
[nin (trip (swp 3 q.dat))]
::
%bytes
:- +(win)
:: find the word index of the actual data.
=/ lic=@ud (div wor 32)
:: learn the bytelength of the data.
=/ len=@ud (snag lic wos)
(decode-bytes-n +(lic) len)
::
[%bytes-n *]
:- (add win +((div (dec n.typ) 32)))
(decode-bytes-n win n.typ)
::
[%array *]
:- +(win)
:: find the word index of the actual data.
=. win (div wor 32)
:: read the elements from their location.
%- tail
%^ decode-array-n ~[t.typ] +(win)
(snag win wos)
::
[%array-n *]
(decode-array-n ~[t.typ] win n.typ)
==
::
++ decode-bytes-n
|= [fro=@ud bys=@ud]
^- octs
:: parse {bys} bytes from {fro}.
:- bys
%+ rsh
:- 3
=+ (mod bys 32)
?:(=(0 -) - (sub 32 -))
%+ rep 8
%- flop
=- (swag [fro -] wos)
+((div (dec bys) 32))
::
++ decode-array-n
::NOTE we take (list etyp) even though we only operate on
:: a single etyp as a workaround for urbit/arvo#673
::NOTE careful! produces lists without type info
=| res=(list)
|* [tys=(list etyp) fro=@ud len=@ud]
^- [@ud (list)]
?~ tys !!
?: =(len 0) [fro (flop `(list)`res)]
=+ (decode-one fro ~[i.tys]) :: [nin=@ud dat=*]
$(res ^+(res [dat res]), fro nin, len (dec len))
--
--
::
:: communicating with rpc nodes
::NOTE https://github.com/ethereum/wiki/wiki/JSON-RPC
::
++ rpc
:: types
::
=> =, abi
=, format
|%
:: raw call data
++ call-data
$: function=@t
arguments=(list data)
==
::
:: raw transaction data
+$ transaction
$: nonce=@ud
gas-price=@ud
gas=@ud
to=address
value=@ud
data=@ux
chain-id=@ux
==
::
:: ethereum json rpc api
::
:: supported requests.
++ request
$% [%eth-block-number ~]
[%eth-call cal=call deb=block]
$: %eth-new-filter
fro=(unit block)
tob=(unit block)
adr=(list address)
top=(list ?(@ux (list @ux)))
==
[%eth-get-block-by-number bon=@ud txs=?]
[%eth-get-filter-logs fid=@ud]
$: %eth-get-logs
fro=(unit block)
tob=(unit block)
adr=(list address)
top=(list ?(@ux (list @ux)))
==
$: %eth-get-logs-by-hash
has=@
adr=(list address)
top=(list ?(@ux (list @ux)))
==
[%eth-get-filter-changes fid=@ud]
[%eth-get-transaction-by-hash txh=@ux]
[%eth-get-transaction-count adr=address =block]
[%eth-get-balance adr=address =block]
[%eth-get-transaction-receipt txh=@ux]
[%eth-send-raw-transaction dat=@ux]
==
::
::TODO clean up & actually use
++ response
$% ::TODO
[%eth-new-filter fid=@ud]
[%eth-get-filter-logs los=(list event-log)]
[%eth-get-logs los=(list event-log)]
[%eth-get-logs-by-hash los=(list event-log)]
[%eth-got-filter-changes los=(list event-log)]
[%eth-transaction-hash haz=@ux]
==
::
++ transaction-result
$: block-hash=(unit @ux)
block-number=(unit @ud)
transaction-index=(unit @ud)
from=@ux
to=(unit @ux)
input=@t
==
::
++ event-log
$: :: null for pending logs
$= mined %- unit
$: input=(unit @ux)
log-index=@ud
transaction-index=@ud
transaction-hash=@ux
block-number=@ud
block-hash=@ux
removed=?
==
::
address=@ux
data=@t
:: event data
::
:: For standard events, the first topic is the event signature
:: hash. For anonymous events, the first topic is the first
:: indexed argument.
:: Note that this does not support the "anonymous event with
:: zero topics" case. This has dubious usability, and using
:: +lest instead of +list saves a lot of ?~ checks.
::
topics=(lest @ux)
==
::
:: data for eth_call.
++ call
$: from=(unit address)
to=address
gas=(unit @ud)
gas-price=(unit @ud)
value=(unit @ud)
data=tape
==
::
:: minimum data needed to construct a read call
++ proto-read-request
$: id=(unit @t)
to=address
call-data
==
::
:: block to operate on.
++ block
$% [%number n=@ud]
[%label l=?(%earliest %latest %pending)]
==
--
::
:: logic
::
|%
++ encode-call
|= call-data
^- tape
::TODO should this check to see if the data matches the function signature?
=- :(weld "0x" - (encode-args arguments))
%+ scag 8
%+ render-hex-bytes 32
%- keccak-256:keccak:crypto
(as-octs:mimes:html function)
::
:: building requests
::
++ json-request
=, eyre
|= [url=purl jon=json]
^- hiss
:^ url %post
%- ~(gas in *math)
~['Content-Type'^['application/json']~]
(some (as-octt (en-json:html jon)))
:: +light-json-request: like json-request, but for %l
::
:: TODO: Exorcising +purl from our system is a much longer term effort;
:: get the current output types for now.
::
++ light-json-request
|= [url=purl:eyre jon=json]
^- request:http
::
:* %'POST'
(crip (en-purl:html url))
~[['content-type' 'application/json']]
(some (as-octt (en-json:html jon)))
==
::
++ batch-read-request
|= req=(list proto-read-request)
^- json
a+(turn req read-request)
::
++ read-request
|= proto-read-request
^- json
%+ request-to-json id
:+ %eth-call
^- call
[~ to ~ ~ ~ `tape`(encode-call function arguments)]
[%label %latest]
::
++ request-to-json
=, enjs:format
|= [riq=(unit @t) req=request]
^- json
%- pairs
=; r=[met=@t pas=(list json)]
::TODO should use request-to-json:rpc:jstd,
:: and probably (fall riq -.req)
:* jsonrpc+s+'2.0'
method+s+met.r
params+a+pas.r
::TODO would just jamming the req noun for id be a bad idea?
?~ riq ~
[id+s+u.riq]~
==
?- -.req
%eth-block-number
['eth_blockNumber' ~]
::
%eth-call
:- 'eth_call'
:~ (eth-call-to-json cal.req)
(block-to-json deb.req)
==
::
%eth-new-filter
:- 'eth_newFilter'
:_ ~
:- %o %- ~(gas by *(map @t json))
=- (murn - same)
^- (list (unit (pair @t json)))
:~ ?~ fro.req ~
`['fromBlock' (block-to-json u.fro.req)]
::
?~ tob.req ~
`['toBlock' (block-to-json u.tob.req)]
::
::TODO fucking tmi
?: =(0 (lent adr.req)) ~
:+ ~ 'address'
?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req)))
:- %a
(turn adr.req (cork address-to-hex tape))
::
?~ top.req ~
:+ ~ 'topics'
(topics-to-json top.req)
==
::
%eth-get-block-by-number
:- 'eth_getBlockByNumber'
:~ (tape (num-to-hex bon.req))
b+txs.req
==
::
%eth-get-filter-logs
['eth_getFilterLogs' (tape (num-to-hex fid.req)) ~]
::
%eth-get-logs
:- 'eth_getLogs'
:_ ~
:- %o %- ~(gas by *(map @t json))
=- (murn - same)
^- (list (unit (pair @t json)))
:~ ?~ fro.req ~
`['fromBlock' (block-to-json u.fro.req)]
::
?~ tob.req ~
`['toBlock' (block-to-json u.tob.req)]
::
?: =(0 (lent adr.req)) ~
:+ ~ 'address'
?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req)))
:- %a
(turn adr.req (cork address-to-hex tape))
::
?~ top.req ~
:+ ~ 'topics'
(topics-to-json top.req)
==
::
%eth-get-logs-by-hash
:- 'eth_getLogs'
:_ ~ :- %o
%- ~(gas by *(map @t json))
=- (murn - same)
^- (list (unit (pair @t json)))
:~ `['blockHash' (tape (transaction-to-hex has.req))]
::
?: =(0 (lent adr.req)) ~
:+ ~ 'address'
?: =(1 (lent adr.req)) (tape (address-to-hex (snag 0 adr.req)))
:- %a
(turn adr.req (cork address-to-hex tape))
::
?~ top.req ~
:+ ~ 'topics'
(topics-to-json top.req)
==
::
%eth-get-filter-changes
['eth_getFilterChanges' (tape (num-to-hex fid.req)) ~]
::
%eth-get-transaction-count
:- 'eth_getTransactionCount'
:~ (tape (address-to-hex adr.req))
(block-to-json block.req)
==
::
%eth-get-balance
:- 'eth_getBalance'
:~ (tape (address-to-hex adr.req))
(block-to-json block.req)
==
::
%eth-get-transaction-by-hash
['eth_getTransactionByHash' (tape (transaction-to-hex txh.req)) ~]
::
%eth-get-transaction-receipt
['eth_getTransactionReceipt' (tape (transaction-to-hex txh.req)) ~]
::
%eth-send-raw-transaction
['eth_sendRawTransaction' (tape (num-to-hex dat.req)) ~]
==
::
++ eth-call-to-json
=, enjs:format
|= cal=call
^- json
:- %o %- ~(gas by *(map @t json))
=- (murn - same)
^- (list (unit (pair @t json)))
:~ ?~ from.cal ~
`['from' (tape (address-to-hex u.from.cal))]
::
`['to' (tape (address-to-hex to.cal))]
::
?~ gas.cal ~
`['gas' (tape (num-to-hex u.gas.cal))]
::
?~ gas-price.cal ~
`['gasPrice' (tape (num-to-hex u.gas-price.cal))]
::
?~ value.cal ~
`['value' (tape (num-to-hex u.value.cal))]
::
?~ data.cal ~
`['data' (tape data.cal)]
==
::
++ block-to-json
|= dob=block
^- json
?- -.dob
%number s+(crip '0' 'x' ((x-co:co 1) n.dob))
%label s+l.dob
==
::
++ topics-to-json
|= tos=(list ?(@ux (list @ux)))
^- json
:- %a
=/ ttj
;: cork
(cury render-hex-bytes 32)
prefix-hex
tape:enjs:format
==
%+ turn tos
|= t=?(@ (list @))
?@ t
?: =(0 t) ~
(ttj `@`t)
a+(turn t ttj)
::
:: parsing responses
::
::TODO ++ parse-response |= json ^- response
::
++ parse-hex-result
|= j=json
^- @
?> ?=(%s -.j)
(hex-to-num p.j)
::
++ parse-eth-new-filter-res parse-hex-result
::
++ parse-eth-block-number parse-hex-result
::
++ parse-transaction-hash parse-hex-result
::
++ parse-eth-get-transaction-count parse-hex-result
::
++ parse-eth-get-balance parse-hex-result
::
++ parse-event-logs
(ar:dejs:format parse-event-log)
::
++ parse-event-log
=, dejs:format
|= log=json
^- event-log
=- ((ot -) log)
:~ =- ['logIndex'^(cu - (mu so))]
|= li=(unit @t)
?~ li ~
=- ``((ou -) log) ::TODO not sure if elegant or hacky.
:~ 'logIndex'^(un (cu hex-to-num so))
'transactionIndex'^(un (cu hex-to-num so))
'transactionHash'^(un (cu hex-to-num so))
'blockNumber'^(un (cu hex-to-num so))
'blockHash'^(un (cu hex-to-num so))
'removed'^(uf | bo)
==
::
address+(cu hex-to-num so)
data+so
::
=- topics+(cu - (ar so))
|= r=(list @t)
^- (lest @ux)
?> ?=([@t *] r)
:- (hex-to-num i.r)
(turn t.r hex-to-num)
==
::
++ parse-transaction-result
=, dejs:format
|= jon=json
~| jon=jon
^- transaction-result
=- ((ot -) jon)
:~ 'blockHash'^_~ :: TODO: fails if maybe-num?
'blockNumber'^maybe-num
'transactionIndex'^maybe-num
from+(cu hex-to-num so)
to+maybe-num
input+so
==
::
++ maybe-num
=, dejs:format
=- (cu - (mu so))
|= r=(unit @t)
?~ r ~
`(hex-to-num u.r)
--
::
:: utilities
::TODO give them better homes!
::
++ num-to-hex
|= n=@
^- tape
%- prefix-hex
?: =(0 n)
"0"
%- render-hex-bytes
(as-octs:mimes:html n)
::
++ address-to-hex
|= a=address
^- tape
%- prefix-hex
(render-hex-bytes 20 `@`a)
::
++ transaction-to-hex
|= h=@
^- tape
%- prefix-hex
(render-hex-bytes 32 h)
::
++ prefix-hex
|= a=tape
^- tape
['0' 'x' a]
::
++ render-hex-bytes
:: atom to string of hex bytes without 0x prefix and dots.
|= a=octs
^- tape
((x-co:co (mul 2 p.a)) q.a)
::
++ pad-to-multiple
|= [wat=tape mof=@ud wer=?(%left %right)]
^- tape
=+ len=(lent wat)
?: =(0 len) (reap mof '0')
=+ mad=(mod len mof)
?: =(0 mad) wat
=+ tad=(reap (sub mof mad) '0')
%- weld
?:(?=(%left wer) [tad wat] [wat tad])
::
++ hex-to-num
|= a=@t
(rash (rsh [3 2] a) hex)
--

1
pkg/arvo/lib/ethereum.hoon Symbolic link
View File

@ -0,0 +1 @@
../../base-dev/lib/ethereum.hoon

View File

@ -1,289 +0,0 @@
:: ethio: Asynchronous Ethereum input/output functions.
::
/- rpc=json-rpc
/+ ethereum, strandio
=, ethereum-types
=, jael
::
=> |%
+$ topics (list ?(@ux (list @ux)))
--
|%
:: +request-rpc: send rpc request, with retry
::
++ request-rpc
|= [url=@ta id=(unit @t) req=request:rpc:ethereum]
=/ m (strand:strandio ,json)
^- form:m
;< res=(list [id=@t =json]) bind:m
(request-batch-rpc-strict url [id req]~)
?: ?=([* ~] res)
(pure:m json.i.res)
%+ strand-fail:strandio
%unexpected-multiple-results
[>(lent res)< ~]
:: +request-batch-rpc-strict: send rpc requests, with retry
::
:: sends a batch request. produces results for all requests in the batch,
:: but only if all of them are successful.
::
++ request-batch-rpc-strict
|= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])]
|^ %+ (retry:strandio results)
`10
attempt-request
::
+$ results (list [id=@t =json])
::
++ attempt-request
=/ m (strand:strandio ,(unit results))
^- form:m
;< responses=(list response:rpc) bind:m
(request-batch-rpc-loose url reqs)
=- ?~ err
(pure:m `res)
(pure:m ~)
%+ roll responses
|= $: rpc=response:rpc
[res=results err=(list [id=@t code=@t message=@t])]
==
?: ?=(%error -.rpc)
[res [+.rpc err]]
?. ?=(%result -.rpc)
[res [['' 'ethio-rpc-fail' (crip <rpc>)] err]]
[[+.rpc res] err]
--
:: +request-batch-rpc-loose: send rpc requests, with retry
::
:: sends a batch request. produces results for all requests in the batch,
:: including the ones that are unsuccessful.
::
++ request-batch-rpc-loose
|= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])]
|^ %+ (retry:strandio results)
`10
attempt-request
::
+$ result response:rpc
+$ results (list response:rpc)
::
++ attempt-request
=/ m (strand:strandio ,(unit results))
^- form:m
=/ =request:http
:* method=%'POST'
url=url
header-list=['Content-Type'^'application/json' ~]
::
^= body
%- some %- as-octt:mimes:html
%- en-json:html
a+(turn reqs request-to-json:rpc:ethereum)
==
;< ~ bind:m
(send-request:strandio request)
;< rep=(unit client-response:iris) bind:m
take-maybe-response:strandio
?~ rep
(pure:m ~)
(parse-responses u.rep)
::
++ parse-responses
|= =client-response:iris
=/ m (strand:strandio ,(unit results))
^- form:m
?> ?=(%finished -.client-response)
?~ full-file.client-response
(pure:m ~)
=/ body=@t q.data.u.full-file.client-response
=/ jon=(unit json) (de-json:html body)
?~ jon
(pure:m ~)
=/ array=(unit (list response:rpc))
((ar:dejs-soft:format parse-one-response) u.jon)
?~ array
(strand-fail:strandio %rpc-result-incomplete-batch >u.jon< ~)
(pure:m array)
::
++ parse-one-response
|= =json
^- (unit response:rpc)
?. &(?=([%o *] json) (~(has by p.json) 'error'))
=/ res=(unit [@t ^json])
%. json
=, dejs-soft:format
(ot id+so result+some ~)
?~ res ~
`[%result u.res]
~| parse-one-response=json
=/ error=(unit [id=@t ^json code=@ta mssg=@t])
%. json
=, dejs-soft:format
:: A 'result' member is present in the error
:: response when using ganache, even though
:: that goes against the JSON-RPC spec
::
(ot id+so result+some error+(ot code+no message+so ~) ~)
?~ error ~
=* err u.error
`[%error id.err code.err mssg.err]
--
::
:: +read-contract: calls a read function on a contract, produces result hex
::
++ read-contract
|= [url=@t req=proto-read-request:rpc:ethereum]
=/ m (strand:strandio ,@t)
;< res=(list [id=@t res=@t]) bind:m
(batch-read-contract-strict url [req]~)
?: ?=([* ~] res)
(pure:m res.i.res)
%+ strand-fail:strandio
%unexpected-multiple-results
[>(lent res)< ~]
:: +batch-read-contract-strict: calls read functions on contracts
::
:: sends a batch request. produces results for all requests in the batch,
:: but only if all of them are successful.
::
++ batch-read-contract-strict
|= [url=@t reqs=(list proto-read-request:rpc:ethereum)]
|^ =/ m (strand:strandio ,results)
^- form:m
;< res=(list [id=@t =json]) bind:m
%+ request-batch-rpc-strict url
(turn reqs proto-to-rpc)
=+ ^- [=results =failures]
(roll res response-to-result)
?~ failures (pure:m results)
(strand-fail:strandio %batch-read-failed-for >failures< ~)
::
+$ results (list [id=@t res=@t])
+$ failures (list [id=@t =json])
::
++ proto-to-rpc
|= proto-read-request:rpc:ethereum
^- [(unit @t) request:rpc:ethereum]
:- id
:+ %eth-call
^- call:rpc:ethereum
[~ to ~ ~ ~ `tape`(encode-call:rpc:ethereum function arguments)]
[%label %latest]
::
++ response-to-result
|= [[id=@t =json] =results =failures]
^+ [results failures]
?: ?=(%s -.json)
[[id^p.json results] failures]
[results [id^json failures]]
--
::
::
++ get-latest-block
|= url=@ta
=/ m (strand:strandio ,block)
^- form:m
;< =json bind:m
(request-rpc url `'block number' %eth-block-number ~)
(get-block-by-number url (parse-eth-block-number:rpc:ethereum json))
::
++ get-block-by-number
|= [url=@ta =number:block]
=/ m (strand:strandio ,block)
^- form:m
|^
%+ (retry:strandio ,block) `10
=/ m (strand:strandio ,(unit block))
^- form:m
;< =json bind:m
%+ request-rpc url
:- `'block by number'
[%eth-get-block-by-number number |]
(pure:m (parse-block json))
::
++ parse-block
|= =json
^- (unit block)
=< ?~(. ~ `[[&1 &2] |2]:u)
^- (unit [@ @ @])
~| json
%. json
=, dejs-soft:format
%- ot
:~ hash+parse-hex
number+parse-hex
'parentHash'^parse-hex
==
::
++ parse-hex |=(=json `(unit @)`(some (parse-hex-result:rpc:ethereum json)))
--
::
++ get-tx-by-hash
|= [url=@ta tx-hash=@ux]
=/ m (strand:strandio transaction-result:rpc:ethereum)
^- form:m
;< =json bind:m
%+ request-rpc url
:* `'tx by hash'
%eth-get-transaction-by-hash
tx-hash
==
%- pure:m
(parse-transaction-result:rpc:ethereum json)
::
++ get-logs-by-hash
|= [url=@ta =hash:block contracts=(list address) =topics]
=/ m (strand:strandio (list event-log:rpc:ethereum))
^- form:m
;< =json bind:m
%+ request-rpc url
:* `'logs by hash'
%eth-get-logs-by-hash
hash
contracts
topics
==
%- pure:m
(parse-event-logs:rpc:ethereum json)
::
++ get-logs-by-range
|= $: url=@ta
contracts=(list address)
=topics
=from=number:block
=to=number:block
==
=/ m (strand:strandio (list event-log:rpc:ethereum))
^- form:m
;< =json bind:m
%+ request-rpc url
:* `'logs by range'
%eth-get-logs
`number+from-number
`number+to-number
contracts
topics
==
%- pure:m
(parse-event-logs:rpc:ethereum json)
::
++ get-next-nonce
|= [url=@ta =address]
=/ m (strand:strandio ,@ud)
^- form:m
;< =json bind:m
%^ request-rpc url `'nonce'
[%eth-get-transaction-count address [%label %latest]]
%- pure:m
(parse-eth-get-transaction-count:rpc:ethereum json)
::
++ get-balance
|= [url=@ta =address]
=/ m (strand:strandio ,@ud)
^- form:m
;< =json bind:m
%^ request-rpc url `'balance'
[%eth-get-balance address [%label %latest]]
%- pure:m
(parse-eth-get-balance:rpc:ethereum json)
--

Some files were not shown because too many files have changed in this diff Show More