mirror of
https://github.com/status-im/pluto.git
synced 2025-02-24 08:28:15 +00:00
Initial commit
This commit is contained in:
commit
f1174feb2d
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
target/
|
||||||
|
/npm-debug.log
|
||||||
|
node_modules/
|
67
MANIFESTO.md
Normal file
67
MANIFESTO.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Development model
|
||||||
|
|
||||||
|
Simple. Opiniated. Adapted to the platform.
|
||||||
|
|
||||||
|
Data based. Hosted on decentralized file storage. Accessible via ETH.
|
||||||
|
|
||||||
|
Simple EDN / hiccup based syntax.
|
||||||
|
Some simple convention (entry point).
|
||||||
|
Simple syntax for simple use cases. More complex available.
|
||||||
|
|
||||||
|
Do we want to allow direct RN model?
|
||||||
|
|
||||||
|
ClojureScript / EDN first, allow JS to.
|
||||||
|
Logic will be distributed as JS.
|
||||||
|
|
||||||
|
Allow to hook in our screens (navigate to).
|
||||||
|
|
||||||
|
Explicitely allow to access some internal subscribe / dispatch.
|
||||||
|
|
||||||
|
Growable. Composable. Reusable.
|
||||||
|
|
||||||
|
https://github.com/juxt/mach/blob/master/examples/poll-twitter/Machfile.edn
|
||||||
|
|
||||||
|
|
||||||
|
### Development process
|
||||||
|
|
||||||
|
Have some simple block based UI to create basic logic
|
||||||
|
|
||||||
|
UI itself can be constructed by drag and drop and sticking componenets together directly
|
||||||
|
|
||||||
|
https://medium.com/@luna_language/luna-the-visual-way-to-create-software-c4db520d6d1e
|
||||||
|
|
||||||
|
https://makecode.com/#about
|
||||||
|
|
||||||
|
See data flowing
|
||||||
|
|
||||||
|
|
||||||
|
### Deployment process
|
||||||
|
|
||||||
|
|
||||||
|
### Discoverability
|
||||||
|
|
||||||
|
https://www.npmjs.com/package/ethereum-ens
|
||||||
|
https://github.com/ipfs/js-ipfs
|
||||||
|
|
||||||
|
## Simple apps to build on top
|
||||||
|
|
||||||
|
Simple split bill app
|
||||||
|
https://trustlines.network/
|
||||||
|
https://livepeer.org/
|
||||||
|
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
Linda model? https://www.inf.ed.ac.uk/teaching/courses/ppls/linda.pdf http://programmingexamples.wikidot.com/linda
|
||||||
|
Semantic query?
|
||||||
|
|
||||||
|
|
||||||
|
How to isolate apps?
|
||||||
|
|
||||||
|
https://github.com/joltup/react-native-threads
|
||||||
|
|
||||||
|
Permission
|
||||||
|
|
||||||
|
Allow local things, warns if leave machine? Or stored?
|
119
build.clj
Normal file
119
build.clj
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
(require '[cljs.build.api :as api]
|
||||||
|
'[clojure.java.shell :as shell]
|
||||||
|
'[clojure.string :as string])
|
||||||
|
|
||||||
|
;;; Configuration.
|
||||||
|
|
||||||
|
(def source-dir "src")
|
||||||
|
|
||||||
|
(def test-dir "test")
|
||||||
|
|
||||||
|
(def compiler-config {:main 'pluto.test
|
||||||
|
:asset-path "js/out"
|
||||||
|
:output-to "resources/public/js/pluto.js"
|
||||||
|
:output-dir "resources/public/js/out"
|
||||||
|
:optimizations :none
|
||||||
|
:static-fns true
|
||||||
|
:closure-defines {"re_frame.trace.trace_enabled_QMARK_" true}
|
||||||
|
:preloads ['day8.re-frame.trace.preload]
|
||||||
|
:source-map true})
|
||||||
|
|
||||||
|
(def test-config {:main 'my-app.test-runner
|
||||||
|
:output-to "target/test.js"
|
||||||
|
:output-dir "target/test"
|
||||||
|
:optimizations :none
|
||||||
|
:source-map true})
|
||||||
|
|
||||||
|
(def test-environment {:SOME_ENV_VAR "some-env-value"})
|
||||||
|
|
||||||
|
(def dev-config (merge compiler-config
|
||||||
|
{:optimizations :none
|
||||||
|
:source-map true}))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Tasks mechanism.
|
||||||
|
|
||||||
|
(defmulti task first)
|
||||||
|
|
||||||
|
(defmethod task :default
|
||||||
|
[args]
|
||||||
|
(let [all-tasks (-> task methods (dissoc :default) keys sort (->> (interpose ", ") (apply str)))]
|
||||||
|
(println "unknown or missing task argument. Choose one of:" all-tasks)
|
||||||
|
(System/exit 1)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Helper functions.
|
||||||
|
|
||||||
|
(defn run-node-tests []
|
||||||
|
(let [{:keys [out err exit]} (shell/sh "node" "target/test.js" :env test-environment)]
|
||||||
|
(println out err)
|
||||||
|
(= exit 0)))
|
||||||
|
|
||||||
|
(defn try-require [ns-sym]
|
||||||
|
(try (require ns-sym) true (catch Exception e (.printStackTrace e) false)))
|
||||||
|
|
||||||
|
(defmacro with-namespaces
|
||||||
|
[namespaces & body]
|
||||||
|
(if (every? try-require namespaces)
|
||||||
|
`(do ~@body)
|
||||||
|
`(do (println "task not available - required dependencies not found")
|
||||||
|
(System/exit 1))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Compiling task.
|
||||||
|
|
||||||
|
(defn compile-once []
|
||||||
|
(api/build source-dir compiler-config))
|
||||||
|
|
||||||
|
(defn compile-refresh []
|
||||||
|
(api/watch source-dir compiler-config))
|
||||||
|
|
||||||
|
(defmethod task "compile" [[_ type]]
|
||||||
|
(case type
|
||||||
|
(nil "once") (compile-once)
|
||||||
|
"watch" (compile-refresh)
|
||||||
|
(do (println "Unknown argument to compile task:" type)
|
||||||
|
(System/exit 1))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Testing task
|
||||||
|
|
||||||
|
(defn test-once []
|
||||||
|
(api/build (api/inputs source-dir test-dir) test-config)
|
||||||
|
(let [success? (run-node-tests)]
|
||||||
|
(System/exit (if success? 0 1))))
|
||||||
|
|
||||||
|
(defn test-refresh []
|
||||||
|
(api/watch (api/inputs source-dir test-dir)
|
||||||
|
(assoc test-config :watch-fn run-node-tests)))
|
||||||
|
|
||||||
|
(defmethod task "test" [[_ type]]
|
||||||
|
(case type
|
||||||
|
(nil "once") (test-once)
|
||||||
|
"watch" (test-refresh)
|
||||||
|
(do (println "Unknown argument to test task:" type)
|
||||||
|
(System/exit 1))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Figwheeling task
|
||||||
|
|
||||||
|
(defmethod task "figwheel" [[_ port]]
|
||||||
|
(with-namespaces [figwheel-sidecar.repl-api]
|
||||||
|
(figwheel-sidecar.repl-api/start-figwheel!
|
||||||
|
{:figwheel-options (cond-> {}
|
||||||
|
port (merge {:http-server-root "public"
|
||||||
|
:server-ip "localhost"
|
||||||
|
:nrepl-port (some-> port Long/parseLong)
|
||||||
|
:on-jsload "pluto.test/run"
|
||||||
|
:nrepl-middleware ["cemerick.piggieback/wrap-cljs-repl"]}))
|
||||||
|
:all-builds [{:id "dev"
|
||||||
|
:figwheel true
|
||||||
|
:source-paths [source-dir]
|
||||||
|
:compiler dev-config}]})
|
||||||
|
(when-not port
|
||||||
|
(figwheel-sidecar.repl-api/cljs-repl))))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Build script entrypoint.
|
||||||
|
|
||||||
|
(task *command-line-args*)
|
14
deps.edn
Normal file
14
deps.edn
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{:deps {org.clojure/clojurescript {:mvn/version "1.9.946"}
|
||||||
|
org.clojure/tools.reader {:mvn/version "1.2.1"}
|
||||||
|
reagent {:mvn/version "0.8.0-alpha2"}
|
||||||
|
re-frame {:mvn/version "0.10.4"}
|
||||||
|
binaryage/devtools {:mvn/version "0.9.9"}
|
||||||
|
day8.re-frame/trace {:mvn/version "0.1.18"}}
|
||||||
|
:paths ["src" "resources"]
|
||||||
|
:aliases {:repl
|
||||||
|
{:extra-deps
|
||||||
|
{;; Figwheel ClojureScript REPL
|
||||||
|
com.cemerick/piggieback {:mvn/version "0.2.2"
|
||||||
|
:exclusions [com.google.javascript/closure-compiler]}
|
||||||
|
figwheel-sidecar {:mvn/version "0.5.14"
|
||||||
|
:exclusions [com.google.javascript/closure-compiler]}}}}}
|
77
resources/presentation/intro.md
Normal file
77
resources/presentation/intro.md
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
## Unified API
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Second slide
|
||||||
|
|
||||||
|
> Best quote ever.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Third slide
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
[div
|
||||||
|
[text ""]]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Competition models
|
||||||
|
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Toshi
|
||||||
|
|
||||||
|
* Regular DApps
|
||||||
|
* chatbot model
|
||||||
|
* no integration / extension points
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Cipher
|
||||||
|
|
||||||
|
* Regular DApps
|
||||||
|
* no chatbot
|
||||||
|
* no integration / extension points
|
||||||
|
|
||||||
|
|
||||||
|
https://github.com/dawnlabs/carbon
|
||||||
|
|
||||||
|
|
||||||
|
## 4 slide
|
||||||
|
|
||||||
|
<div class="test">
|
||||||
|
TOTO
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="fragment" data-fragment-index="3">Appears last</div>
|
||||||
|
<div class="fragment" data-fragment-index="1">Appears first</div>
|
||||||
|
<div class="fragment" data-fragment-index="2">Appears second</div>
|
||||||
|
|
||||||
|
<button onclick="alert('Vous avez cliqué !');">
|
||||||
|
Hello
|
||||||
|
</button>
|
||||||
|
|
||||||
|
|
||||||
|
Note: speaker notes FTW!
|
||||||
|
|
||||||
|
|
||||||
|
## Security
|
||||||
|
|
||||||
|
Do not reproduce web failures (cookies, localStorage)
|
||||||
|
|
||||||
|
Allow access by default?
|
||||||
|
|
||||||
|
But data sending preventing by default
|
||||||
|
|
||||||
|
No external connection allowed
|
||||||
|
Permission per remote host
|
||||||
|
|
||||||
|
https://blog.colony.io/securing-local-storage-for-dapps-33dc4d52e1fd
|
||||||
|
|
||||||
|
|
||||||
|
Dev model:
|
||||||
|
similar to REST API (expose actions, not data model)
|
||||||
|
http://www.amundsen.com/blog/archives/1167
|
261
resources/presentation/status.css
Normal file
261
resources/presentation/status.css
Normal file
@ -0,0 +1,261 @@
|
|||||||
|
/**
|
||||||
|
* A simple theme for reveal.js presentations, similar
|
||||||
|
* to the default theme. The accent color is darkblue.
|
||||||
|
*
|
||||||
|
* This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
|
||||||
|
* reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
|
||||||
|
*/
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
|
||||||
|
section.has-dark-background, section.has-dark-background h1, section.has-dark-background h2, section.has-dark-background h3, section.has-dark-background h4, section.has-dark-background h5, section.has-dark-background h6 {
|
||||||
|
color: #fff; }
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* GLOBAL STYLES
|
||||||
|
*********************************************/
|
||||||
|
body {
|
||||||
|
background-color: #4957b8; }
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
font-family: "Lato", sans-serif;
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: normal;
|
||||||
|
color: #fff; }
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(0, 0, 0, 0.99);
|
||||||
|
text-shadow: none; }
|
||||||
|
|
||||||
|
.reveal .slides > section,
|
||||||
|
.reveal .slides > section > section {
|
||||||
|
line-height: 1.3;
|
||||||
|
font-weight: inherit; }
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* HEADERS
|
||||||
|
*********************************************/
|
||||||
|
.reveal h1,
|
||||||
|
.reveal h2,
|
||||||
|
.reveal h3,
|
||||||
|
.reveal h4,
|
||||||
|
.reveal h5,
|
||||||
|
.reveal h6 {
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
color: #fff;
|
||||||
|
font-family: "PostGrotesk-Medium", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1.2;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-transform: none;
|
||||||
|
text-shadow: none;
|
||||||
|
word-wrap: break-word; }
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
font-size: 3.77em; }
|
||||||
|
|
||||||
|
.reveal h2 {
|
||||||
|
font-size: 2.11em; }
|
||||||
|
|
||||||
|
.reveal h3 {
|
||||||
|
font-size: 1.55em; }
|
||||||
|
|
||||||
|
.reveal h4 {
|
||||||
|
font-size: 1em; }
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
text-shadow: none; }
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* OTHER
|
||||||
|
*********************************************/
|
||||||
|
.reveal p {
|
||||||
|
margin: 20px 0;
|
||||||
|
line-height: 1.3; }
|
||||||
|
|
||||||
|
/* Ensure certain elements are never larger than the slide itself */
|
||||||
|
.reveal img,
|
||||||
|
.reveal video,
|
||||||
|
.reveal iframe {
|
||||||
|
max-width: 95%;
|
||||||
|
max-height: 95%; }
|
||||||
|
|
||||||
|
.reveal strong,
|
||||||
|
.reveal b {
|
||||||
|
font-weight: bold; }
|
||||||
|
|
||||||
|
.reveal em {
|
||||||
|
font-style: italic; }
|
||||||
|
|
||||||
|
.reveal ol,
|
||||||
|
.reveal dl,
|
||||||
|
.reveal ul {
|
||||||
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
|
margin: 0 0 0 1em; }
|
||||||
|
|
||||||
|
.reveal ol {
|
||||||
|
list-style-type: decimal; }
|
||||||
|
|
||||||
|
.reveal ul {
|
||||||
|
list-style-type: disc; }
|
||||||
|
|
||||||
|
.reveal ul ul {
|
||||||
|
list-style-type: square; }
|
||||||
|
|
||||||
|
.reveal ul ul ul {
|
||||||
|
list-style-type: circle; }
|
||||||
|
|
||||||
|
.reveal ul ul,
|
||||||
|
.reveal ul ol,
|
||||||
|
.reveal ol ol,
|
||||||
|
.reveal ol ul {
|
||||||
|
display: block;
|
||||||
|
margin-left: 40px; }
|
||||||
|
|
||||||
|
.reveal dt {
|
||||||
|
font-weight: bold; }
|
||||||
|
|
||||||
|
.reveal dd {
|
||||||
|
margin-left: 40px; }
|
||||||
|
|
||||||
|
.reveal blockquote {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 70%;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 5px;
|
||||||
|
font-style: italic;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2); }
|
||||||
|
|
||||||
|
.reveal blockquote p:first-child,
|
||||||
|
.reveal blockquote p:last-child {
|
||||||
|
display: inline-block; }
|
||||||
|
|
||||||
|
.reveal q {
|
||||||
|
font-style: italic; }
|
||||||
|
|
||||||
|
.reveal pre {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 90%;
|
||||||
|
margin: 20px auto;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 0.55em;
|
||||||
|
font-family: monospace;
|
||||||
|
line-height: 1.2em;
|
||||||
|
word-wrap: break-word;
|
||||||
|
box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.3); }
|
||||||
|
|
||||||
|
.reveal code {
|
||||||
|
font-family: monospace;
|
||||||
|
text-transform: none; }
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 400px;
|
||||||
|
word-wrap: normal; }
|
||||||
|
|
||||||
|
.reveal table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0; }
|
||||||
|
|
||||||
|
.reveal table th {
|
||||||
|
font-weight: bold; }
|
||||||
|
|
||||||
|
.reveal table th,
|
||||||
|
.reveal table td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
border-bottom: 1px solid; }
|
||||||
|
|
||||||
|
.reveal table th[align="center"],
|
||||||
|
.reveal table td[align="center"] {
|
||||||
|
text-align: center; }
|
||||||
|
|
||||||
|
.reveal table th[align="right"],
|
||||||
|
.reveal table td[align="right"] {
|
||||||
|
text-align: right; }
|
||||||
|
|
||||||
|
.reveal table tbody tr:last-child th,
|
||||||
|
.reveal table tbody tr:last-child td {
|
||||||
|
border-bottom: none; }
|
||||||
|
|
||||||
|
.reveal sup {
|
||||||
|
vertical-align: super; }
|
||||||
|
|
||||||
|
.reveal sub {
|
||||||
|
vertical-align: sub; }
|
||||||
|
|
||||||
|
.reveal small {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6em;
|
||||||
|
line-height: 1.2em;
|
||||||
|
vertical-align: top; }
|
||||||
|
|
||||||
|
.reveal small * {
|
||||||
|
vertical-align: top; }
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* LINKS
|
||||||
|
*********************************************/
|
||||||
|
.reveal a {
|
||||||
|
color: #00008B;
|
||||||
|
text-decoration: none;
|
||||||
|
-webkit-transition: color .15s ease;
|
||||||
|
-moz-transition: color .15s ease;
|
||||||
|
transition: color .15s ease; }
|
||||||
|
|
||||||
|
.reveal a:hover {
|
||||||
|
color: #0000f1;
|
||||||
|
text-shadow: none;
|
||||||
|
border: none; }
|
||||||
|
|
||||||
|
.reveal .roll span:after {
|
||||||
|
color: #fff;
|
||||||
|
background: #00003f; }
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* IMAGES
|
||||||
|
*********************************************/
|
||||||
|
.reveal section img {
|
||||||
|
margin: 15px 0px;
|
||||||
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
border: 4px solid #000;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); }
|
||||||
|
|
||||||
|
.reveal section img.plain {
|
||||||
|
border: 0;
|
||||||
|
box-shadow: none; }
|
||||||
|
|
||||||
|
.reveal a img {
|
||||||
|
-webkit-transition: all .15s linear;
|
||||||
|
-moz-transition: all .15s linear;
|
||||||
|
transition: all .15s linear; }
|
||||||
|
|
||||||
|
.reveal a:hover img {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border-color: #00008B;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* NAVIGATION CONTROLS
|
||||||
|
*********************************************/
|
||||||
|
.reveal .controls {
|
||||||
|
color: #00008B; }
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PROGRESS BAR
|
||||||
|
*********************************************/
|
||||||
|
.reveal .progress {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
color: #00008B; }
|
||||||
|
|
||||||
|
.reveal .progress span {
|
||||||
|
-webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
|
||||||
|
-moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
|
||||||
|
transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
|
1
scripts/figwheel.sh
Executable file
1
scripts/figwheel.sh
Executable file
@ -0,0 +1 @@
|
|||||||
|
clj -R:repl build.clj figwheel
|
46
src/pluto/README.md
Normal file
46
src/pluto/README.md
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Use case
|
||||||
|
|
||||||
|
## Hello world
|
||||||
|
|
||||||
|
A dumb text showing "Hello world"
|
||||||
|
|
||||||
|
QmbXjFEF6WbxNb4gyZE3JkEGG3ur4fmDgvo5vsQvdy95vW
|
||||||
|
|
||||||
|
[screen
|
||||||
|
[text "Hello world"]]
|
||||||
|
|
||||||
|
## Basic data interaction
|
||||||
|
|
||||||
|
inc/dec buttons, some text showing the count
|
||||||
|
|
||||||
|
```main.edn
|
||||||
|
:main
|
||||||
|
[screen
|
||||||
|
[text #subscribe ::counter]
|
||||||
|
[button {:on-press #dispatch ::dec}
|
||||||
|
"Dec"]
|
||||||
|
[button {:on-press #dispatch ::inc}
|
||||||
|
"Inc"]]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Basic transaction
|
||||||
|
|
||||||
|
Send some STT to an exeisting address
|
||||||
|
|
||||||
|
## Reuse screens
|
||||||
|
|
||||||
|
Browse contact, select one, then open wallet send transaction screen pre-populated with this contact.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## TO think about
|
||||||
|
|
||||||
|
# ENS
|
||||||
|
# IPFS storage
|
||||||
|
|
||||||
|
### Remotely load JS code in react-native
|
||||||
|
https://github.com/MaxLeap/HotLoad-SDK
|
||||||
|
https://github.com/Microsoft/react-native-code-push
|
||||||
|
https://docs.expo.io/versions/latest/guides/how-expo-works.html
|
||||||
|
https://www.aerofs.com/reactnativeautoupdater-dynamic-updates-to-react-native-apps/
|
||||||
|
https://github.com/redbooth/react-native-auto-updater/
|
3
src/pluto/core.cljc
Normal file
3
src/pluto/core.cljc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
(ns pluto.core
|
||||||
|
)
|
||||||
|
|
26
src/pluto/feedback.md
Normal file
26
src/pluto/feedback.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IP company
|
||||||
|
Push a number of papers
|
||||||
|
Lots of photo / video to take
|
||||||
|
|
||||||
|
|
||||||
|
Doctor
|
||||||
|
Ask to do tests
|
||||||
|
Do some tests
|
||||||
|
Then chat with Doctor
|
||||||
|
Transfer to Doctor
|
||||||
|
=> chat bot?
|
||||||
|
|
||||||
|
german iOT (manufacturing as a service)
|
||||||
|
Machine with crypto integration
|
||||||
|
Interraction with machine directly?
|
||||||
|
|
||||||
|
airbnb on blockchain
|
||||||
|
chat representing the company?
|
||||||
|
|
||||||
|
web3.js
|
||||||
|
constantly breaking
|
||||||
|
make send transaction easy
|
||||||
|
|
14
src/pluto/hiccup.cljc
Normal file
14
src/pluto/hiccup.cljc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
(ns pluto.hiccup
|
||||||
|
(:require [clojure.spec.alpha :as spec]))
|
||||||
|
|
||||||
|
(spec/def :hiccup/form
|
||||||
|
(spec/or
|
||||||
|
:string string?
|
||||||
|
:number number?
|
||||||
|
:element :hiccup/element))
|
||||||
|
|
||||||
|
(spec/def :hiccup/element
|
||||||
|
(spec/cat
|
||||||
|
:tag keyword?
|
||||||
|
:attrs (spec/? map?)
|
||||||
|
:children (spec/* :hiccup/form)))
|
88
src/pluto/pres.md
Normal file
88
src/pluto/pres.md
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
## Add a slide on ideas
|
||||||
|
## Remove side by side code comparison
|
||||||
|
|
||||||
|
# 14
|
||||||
|
|
||||||
|
## Transparency
|
||||||
|
We are all about open blockchain interactions. Rely on standard.
|
||||||
|
Security is one of our pillar so we require transparency. We don't believe in security by obscurity.
|
||||||
|
100% of our codebase is opensource. Accessible for everyone to see, participate.
|
||||||
|
##Contribution
|
||||||
|
That's the main idea behind OpenBounty. Anyone can join and contribute to the product, and make some money.
|
||||||
|
Actually we even use those contributions to hire new people.
|
||||||
|
Oh BTW even openbounty is opensource!
|
||||||
|
One fancy DApp you can use and see how it works.
|
||||||
|
##Audit
|
||||||
|
Because all source code is available you can check what and how things are done.
|
||||||
|
BTW we are planning a security audit that will be publicly available.
|
||||||
|
##Tweak
|
||||||
|
You can even tweak the app yourself, build it and use it as is on your phone!
|
||||||
|
|
||||||
|
# 15
|
||||||
|
|
||||||
|
2 main projects. More are coming!
|
||||||
|
|
||||||
|
status-react
|
||||||
|
UI part of this app. This is whera chat, wallet and DApp browsing is implemented.
|
||||||
|
One codebase for iOS and android.
|
||||||
|
Using modern stack (ClojureScript, react-native).
|
||||||
|
Providing best user experience we can.
|
||||||
|
Currently going through massive simplification and performance oriented work.
|
||||||
|
|
||||||
|
status-go
|
||||||
|
Our layer to the ethereum world, built on top of ethereum libraries
|
||||||
|
ethereum is desktop technology, so all optimization work happen here
|
||||||
|
Also heavily invested in optimization of ethereum itself and contributing to new technologies (LES2, new whisper)
|
||||||
|
|
||||||
|
Others: status-desktop, status-electron, hardwallet
|
||||||
|
|
||||||
|
# 16
|
||||||
|
|
||||||
|
Even part of our process is opensource
|
||||||
|
You can see our proposition as they arrive, vote on them, comment on them
|
||||||
|
Look at ideas repo
|
||||||
|
|
||||||
|
# 17
|
||||||
|
|
||||||
|
Not a typical app
|
||||||
|
Not a typical client server app
|
||||||
|
Part of a mesh network
|
||||||
|
Part of the ethereum network
|
||||||
|
Status is a complete light node
|
||||||
|
not mining obviously
|
||||||
|
Relay whisper messages
|
||||||
|
Opens door to a lot of inovation
|
||||||
|
|
||||||
|
Also remember status-desktop has same stack
|
||||||
|
Why not iOT stuff?
|
||||||
|
|
||||||
|
# 18
|
||||||
|
|
||||||
|
Open inovation internally
|
||||||
|
You have an idea? Make a proposition, convince people, work on it
|
||||||
|
Example of status-desktop POC
|
||||||
|
Alternative to our current QT effort
|
||||||
|
A new effort from scratch using electron JS tech stack
|
||||||
|
Reuse our logic
|
||||||
|
Already functional and usable, even if still basic
|
||||||
|
|
||||||
|
# 19
|
||||||
|
|
||||||
|
Mesh newtwork
|
||||||
|
Issues, not enough nodes
|
||||||
|
Could be controlled by big miners?
|
||||||
|
A need for much more small nodes
|
||||||
|
|
||||||
|
# 20
|
||||||
|
|
||||||
|
Mesh with status nodes included
|
||||||
|
phone
|
||||||
|
desktop
|
||||||
|
long running nodes on top of raspberry
|
||||||
|
|
||||||
|
How to incentivize people having long running nodes?
|
||||||
|
Incentivized layers
|
||||||
|
* swarm for files
|
||||||
|
* streaming
|
||||||
|
* relayer
|
||||||
|
Part of the answer?
|
12
src/pluto/semantic.md
Normal file
12
src/pluto/semantic.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
how it maps to db
|
||||||
|
|
||||||
|
switch network
|
||||||
|
|
||||||
|
account
|
||||||
|
addresses
|
||||||
|
whisper key
|
||||||
|
|
||||||
|
wallet
|
||||||
|
local
|
||||||
|
hardware
|
174
src/pluto/test.cljs
Normal file
174
src/pluto/test.cljs
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
(ns pluto.test
|
||||||
|
(:require [clojure.tools.reader.edn :as edn]
|
||||||
|
[clojure.walk :as walk]
|
||||||
|
[reagent.core :as reagent]
|
||||||
|
[re-frame.core :as rf]
|
||||||
|
[re-frame.loggers :as rf.loggers]
|
||||||
|
[clojure.string :as str]
|
||||||
|
[devtools.core :as devtools]))
|
||||||
|
|
||||||
|
(devtools/install!)
|
||||||
|
|
||||||
|
;; A detailed walk-through of this source code is provided in the docs:
|
||||||
|
;; https://github.com/Day8/re-frame/blob/master/docs/CodeWalkthrough.md
|
||||||
|
|
||||||
|
;; -- Domino 1 - Event Dispatch -----------------------------------------------
|
||||||
|
|
||||||
|
(defn dispatch-timer-event
|
||||||
|
[]
|
||||||
|
(let [now (js/Date.)]
|
||||||
|
(rf/dispatch [:timer now]))) ;; <-- dispatch used
|
||||||
|
|
||||||
|
;; Call the dispatching function every second.
|
||||||
|
;; `defonce` is like `def` but it ensures only one instance is ever
|
||||||
|
;; created in the face of figwheel hot-reloading of this file.
|
||||||
|
(defonce do-timer (js/setInterval dispatch-timer-event 1000))
|
||||||
|
|
||||||
|
|
||||||
|
;; -- Domino 2 - Event Handlers -----------------------------------------------
|
||||||
|
|
||||||
|
(rf/reg-event-db ;; sets up initial application state
|
||||||
|
:initialize ;; usage: (dispatch [:initialize])
|
||||||
|
(fn [_ _] ;; the two parameters are not important here, so use _
|
||||||
|
{:time (js/Date.) ;; What it returns becomes the new application state
|
||||||
|
:time-color "#f88"})) ;; so the application state will initially be a map with two keys
|
||||||
|
|
||||||
|
|
||||||
|
(rf/reg-event-db ;; usage: (dispatch [:time-color-change 34562])
|
||||||
|
:time-color-change ;; dispatched when the user enters a new colour into the UI text field
|
||||||
|
(fn [db [_ new-color-value]] ;; -db event handlers given 2 parameters: current application state and event (a vector)
|
||||||
|
(assoc db :time-color new-color-value))) ;; compute and return the new application state
|
||||||
|
|
||||||
|
|
||||||
|
(rf/reg-event-db ;; usage: (dispatch [:timer a-js-Date])
|
||||||
|
:timer ;; every second an event of this kind will be dispatched
|
||||||
|
(fn [db [_ new-time]] ;; note how the 2nd parameter is destructured to obtain the data value
|
||||||
|
(assoc db :time new-time))) ;; compute and return the new application state
|
||||||
|
|
||||||
|
|
||||||
|
;; -- Domino 4 - Query -------------------------------------------------------
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:time
|
||||||
|
(fn [db _] ;; db is current app state. 2nd unused param is query vector
|
||||||
|
(:time db))) ;; return a query computation over the application state
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:time-color
|
||||||
|
(fn [db _]
|
||||||
|
(:time-color db)))
|
||||||
|
|
||||||
|
|
||||||
|
;; -- Domino 5 - View Functions ----------------------------------------------
|
||||||
|
|
||||||
|
(defn clock
|
||||||
|
[]
|
||||||
|
[:div.example-clock
|
||||||
|
{:style {:color @(rf/subscribe [:time-color])}}
|
||||||
|
(-> @(rf/subscribe [:time])
|
||||||
|
.toTimeString
|
||||||
|
(str/split " ")
|
||||||
|
first)])
|
||||||
|
|
||||||
|
(defn color-input
|
||||||
|
[]
|
||||||
|
[:div.color-input
|
||||||
|
"Time color: "
|
||||||
|
[:input {:type "text"
|
||||||
|
:value @(rf/subscribe [:time-color])
|
||||||
|
:on-change #(rf/dispatch [:time-color-change (-> % .-target .-value)])}]]) ;; <---
|
||||||
|
|
||||||
|
(defn screen [props content]
|
||||||
|
[:div props content])
|
||||||
|
|
||||||
|
(defn button [props content]
|
||||||
|
[:button props content])
|
||||||
|
|
||||||
|
(defn text [props content]
|
||||||
|
[:text props content])
|
||||||
|
|
||||||
|
(def components {:text text
|
||||||
|
:screen screen})
|
||||||
|
|
||||||
|
(defn my-unknown [tag val]
|
||||||
|
{:unknown-tag tag :value val})
|
||||||
|
|
||||||
|
(defn subscribe [o]
|
||||||
|
@(rf/subscribe o))
|
||||||
|
|
||||||
|
(defn parse-view [s]
|
||||||
|
(edn/read-string {:default my-unknown :readers {'subscribe subscribe}}
|
||||||
|
s))
|
||||||
|
|
||||||
|
(defn split [[o & rest]]
|
||||||
|
(apply conj [((keyword o) components)] rest))
|
||||||
|
|
||||||
|
(defn translate-components [o]
|
||||||
|
(walk/postwalk (fn [x]
|
||||||
|
(if (vector? x)
|
||||||
|
(split o)
|
||||||
|
x)) o))
|
||||||
|
|
||||||
|
(defn body [r f]
|
||||||
|
(.then r f))
|
||||||
|
|
||||||
|
(defn load-http [s f]
|
||||||
|
(let [xhr (js/XMLHttpRequest.)]
|
||||||
|
(.open xhr "GET" (str s "/main.edn") true)
|
||||||
|
(.send xhr nil)
|
||||||
|
(set! (.-onreadystatechange xhr)
|
||||||
|
#(when (= (.-readyState xhr) 4)
|
||||||
|
(f (.-response xhr))))))
|
||||||
|
|
||||||
|
(defn ipfs->map [o]
|
||||||
|
{:content (.toString (get o "content") "utf8")})
|
||||||
|
|
||||||
|
(defn parse-ipfs-files [err o]
|
||||||
|
(println "PARSE" o)
|
||||||
|
(let [v (js->clj o)]
|
||||||
|
(println (map ipfs->map v))))
|
||||||
|
|
||||||
|
(defn dump [err]
|
||||||
|
(println "ERR" err)
|
||||||
|
)
|
||||||
|
|
||||||
|
(defn load-ipfs [ipfs f]
|
||||||
|
(let [o ((.-get (.-files ipfs)) "QmbXjFEF6WbxNb4gyZE3JkEGG3ur4fmDgvo5vsQvdy95vW")]
|
||||||
|
(js/console.log ">>" o)))
|
||||||
|
|
||||||
|
(defn load-view [s]
|
||||||
|
(-> s
|
||||||
|
parse-view
|
||||||
|
translate-components))
|
||||||
|
|
||||||
|
(def warn (js/console.warn.bind js/console))
|
||||||
|
(rf.loggers/set-loggers!
|
||||||
|
{:warn (fn [& args]
|
||||||
|
(cond
|
||||||
|
(= "re-frame: overwriting" (first args)) nil
|
||||||
|
:else (apply warn args)))})
|
||||||
|
|
||||||
|
(enable-console-print!)
|
||||||
|
|
||||||
|
(defn render [h]
|
||||||
|
(println "RENDER" h)
|
||||||
|
;document.getElementById('myframe1').contentWindow.
|
||||||
|
(let [frame (js/document.getElementById "frame")]
|
||||||
|
(println "FRAME" frame)
|
||||||
|
(println "doc" (aget frame "contentWindow") (.getElementById (aget frame "contentWindow" "document") "app") )
|
||||||
|
(reagent/render h (.-body (aget frame "contentWindow" "document")))))
|
||||||
|
|
||||||
|
(defn ^:export run
|
||||||
|
[]
|
||||||
|
(println "RUN")
|
||||||
|
(rf/clear-subscription-cache!)
|
||||||
|
(rf/dispatch-sync [:initialize]) ;; puts a value into application state
|
||||||
|
|
||||||
|
(load-http "hello"
|
||||||
|
#(-> %
|
||||||
|
load-view
|
||||||
|
render))
|
||||||
|
|
||||||
|
#_
|
||||||
|
(let [ipfs (js/Ipfs.)]
|
||||||
|
(load-ipfs ipfs render)))
|
Loading…
x
Reference in New Issue
Block a user