From 171445418f323689ab61b9e79494ba2b42b6278a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=83=9D=E3=83=BC=E3=83=AB=20=E3=82=A6=E3=82=A7=E3=83=83?= =?UTF-8?q?=E3=83=96?= Date: Thu, 12 Jul 2018 10:21:42 -0500 Subject: [PATCH] Initial commit --- CONTRIBUTING.md | 2 +- README.md | 58 +- client.js | 69 + content/.vuepress/config.js => config.js | 17 +- content/.vuepress/components/Ecosystem.vue | 913 - content/.vuepress/components/EditLink.vue | 36 - .../.vuepress/components/EmailSubscribe.vue | 181 - .../components/EmailSubscribeLarge.vue | 104 - content/.vuepress/components/FeatureLinks.vue | 110 - content/.vuepress/components/GithubFeed.vue | 340 - .../.vuepress/components/MissionStatement.vue | 35 - content/.vuepress/components/Sidebar.vue | 42 - content/.vuepress/components/Sitemap.vue | 25 - content/.vuepress/components/Slate.vue | 366 - content/.vuepress/components/Tour/Hook.vue | 447 - content/.vuepress/components/Tour/Step1.vue | 140 - content/.vuepress/components/Tour/Step2.vue | 262 - content/.vuepress/components/Tour/Step3.vue | 139 - content/.vuepress/event-bus.js | 4 - content/.vuepress/js/jquery.highlight.js | 109 - content/.vuepress/public/api.md | 1656 -- .../.vuepress/public/fonts/FontAwesome.otf | Bin 62856 -> 0 bytes .../public/fonts/fontawesome-webfont.eot | Bin 38205 -> 0 bytes .../public/fonts/fontawesome-webfont.svg | 414 - .../public/fonts/fontawesome-webfont.ttf | Bin 80652 -> 0 bytes .../public/fonts/fontawesome-webfont.woff | Bin 44432 -> 0 bytes content/.vuepress/public/slate-logo.png | Bin 3507 -> 0 bytes content/.vuepress/public/slate-navbar.png | Bin 96 -> 0 bytes content/.vuepress/scss/_fonts.scss | 260 - content/.vuepress/scss/_variables.scss | 2 - content/.vuepress/scss/fonts/FontAwesome.otf | Bin 62856 -> 0 bytes .../scss/fonts/fontawesome-webfont.eot | Bin 38205 -> 0 bytes .../scss/fonts/fontawesome-webfont.svg | 414 - .../scss/fonts/fontawesome-webfont.ttf | Bin 80652 -> 0 bytes .../scss/fonts/fontawesome-webfont.woff | Bin 44432 -> 0 bytes content/.vuepress/scss/init/_normalize.scss | 578 - content/.vuepress/scss/pages/_overview.scss | 2 - content/.vuepress/theme/Layout.vue | 410 - content/api/index.md | 8 - content/build/index.md | 54 - content/community/index.md | 32 - content/contribute/index.md | 125 - content/documentation.md | 13 - content/glossary.md | 335 - content/index.md | 4 - content/overview/index.md | 37 - content/resources/claimtrie.md | 72 - content/resources/encrypt-lbrycrd.md | 9 - content/resources/index.md | 4 - content/resources/lbry-claimtrie.md | 77 - content/resources/lbry.md | 55 - content/resources/lbrycrd.md | 55 - content/resources/pow.md | 19 - content/resources/regtest-setup.md | 201 - content/resources/repository-standards.md | 101 - content/resources/schema.md | 130 - content/resources/signing-claim.md | 129 - content/resources/uri.md | 102 - content/sitemap.md | 5 - content/subscribe/index.md | 7 - content/tour/index.md | 6 - content/whitepaper.md | 27 - helpers/pa.js | 30 + helpers/slack.js | 30 + index.js | 1 + npm-shrinkwrap.json | 14115 ---------------- package.json | 83 +- public/apple-touch-icon.png | Bin 0 -> 3289 bytes public/css/style.css | 1 + public/css/style.css.map | 1 + .../.vuepress/public => public}/favicon.ico | Bin .../.vuepress/public => public}/favicon.svg | 0 public/humans.txt | 17 + .../media/images/background-a.jpg | Bin .../media/images}/carlsagan2.jpg | Bin .../media/images}/doge-meme.jpg | Bin .../media/images/grid.png | Bin .../media/images}/lbry-green.png | Bin .../media/images/lbry-overview.png | Bin .../media/images/missing.png | Bin .../.vuepress => public}/media/svg/anchor.svg | 0 .../.vuepress => public}/media/svg/chat.svg | 0 .../media/svg/discord.svg | 0 .../.vuepress => public}/media/svg/down.svg | 0 .../.vuepress => public}/media/svg/flag.svg | 0 .../media/svg/keyboard.svg | 0 .../media/svg/logo--white.svg | 0 .../.vuepress => public}/media/svg/logo.svg | 0 .../media/svg/monitor.svg | 0 .../.vuepress => public}/media/svg/reddit.svg | 0 .../.vuepress => public}/media/svg/slack.svg | 0 .../media/svg/text-logo--white.svg | 0 .../media/svg/text-logo.svg | 0 public/scripts/app.js | 55 + public/scripts/vendor/zepto.js | 2 + public/type/karmilla/400.woff | Bin 0 -> 35776 bytes public/type/karmilla/400.woff2 | Bin 0 -> 25488 bytes public/type/karmilla/400i.woff | Bin 0 -> 19540 bytes public/type/karmilla/700.woff | Bin 0 -> 30840 bytes public/type/karmilla/700.woff2 | Bin 0 -> 22388 bytes public/type/karmilla/700i.woff | Bin 0 -> 22444 bytes public/type/playfair/400.woff | Bin 0 -> 38832 bytes public/type/playfair/400.woff2 | Bin 0 -> 31436 bytes public/type/playfair/400i.woff | Bin 0 -> 41876 bytes public/type/playfair/400i.woff2 | Bin 0 -> 33836 bytes public/type/playfair/700.woff | Bin 0 -> 40896 bytes public/type/playfair/700.woff2 | Bin 0 -> 33196 bytes public/type/playfair/700i.woff | Bin 0 -> 42480 bytes public/type/playfair/700i.woff2 | Bin 0 -> 34524 bytes {content/.vuepress/scss => sass}/_layout.scss | 2 +- .../.vuepress/scss => sass}/init/_base.scss | 0 .../.vuepress/scss => sass}/init/_colors.scss | 0 .../scss => sass}/init/_extends.scss | 0 .../.vuepress/scss => sass}/init/_mixins.scss | 0 .../scss => sass}/pages/_contributing.scss | 0 .../scss => sass}/pages/_documentation.scss | 0 .../.vuepress/scss => sass}/pages/_home.scss | 0 .../.vuepress/scss => sass}/pages/_page.scss | 10 + .../scss => sass}/partials/_animation.scss | 0 sass/partials/_ecosystem.scss | 398 + sass/partials/_email-subscribe.scss | 121 + .../scss => sass}/partials/_footer.scss | 0 sass/partials/_github-feed.scss | 182 + sass/partials/_mission-statement.scss | 23 + .../scss => sass}/partials/_modal.scss | 0 .../scss => sass}/partials/_navigation.scss | 2 +- sass/style.scss | 26 + .../.vuepress/scss => sass}/type/_karla.scss | 0 server.js | 214 +- test/api.js | 76 - views/components/html.js | 32 + views/components/layout.js | 30 + views/pages/_404.js | 25 + views/pages/_error.js | 26 + views/pages/github-feed.js | 169 + views/pages/home.js | 126 + views/pages/overview.md | 37 + views/pages/page.js | 108 + views/pages/resources.js | 117 + views/partials/ecosystem-scripts.js | 250 + views/partials/ecosystem.js | 295 + views/partials/edit-link.js | 33 + views/partials/email-subscribe.js | 32 + views/partials/footer.js | 66 + views/partials/github-feed.js | 197 + views/partials/head.js | 60 + views/partials/mission-statement.js | 25 + views/partials/navigation.js | 71 + views/partials/noscript.js | 25 + views/show.js | 33 + 150 files changed, 2883 insertions(+), 23005 deletions(-) mode change 100644 => 100755 README.md create mode 100755 client.js rename content/.vuepress/config.js => config.js (54%) delete mode 100644 content/.vuepress/components/Ecosystem.vue delete mode 100644 content/.vuepress/components/EditLink.vue delete mode 100644 content/.vuepress/components/EmailSubscribe.vue delete mode 100644 content/.vuepress/components/EmailSubscribeLarge.vue delete mode 100644 content/.vuepress/components/FeatureLinks.vue delete mode 100644 content/.vuepress/components/GithubFeed.vue delete mode 100644 content/.vuepress/components/MissionStatement.vue delete mode 100644 content/.vuepress/components/Sidebar.vue delete mode 100644 content/.vuepress/components/Sitemap.vue delete mode 100644 content/.vuepress/components/Slate.vue delete mode 100644 content/.vuepress/components/Tour/Hook.vue delete mode 100644 content/.vuepress/components/Tour/Step1.vue delete mode 100644 content/.vuepress/components/Tour/Step2.vue delete mode 100644 content/.vuepress/components/Tour/Step3.vue delete mode 100644 content/.vuepress/event-bus.js delete mode 100644 content/.vuepress/js/jquery.highlight.js delete mode 100644 content/.vuepress/public/api.md delete mode 100644 content/.vuepress/public/fonts/FontAwesome.otf delete mode 100644 content/.vuepress/public/fonts/fontawesome-webfont.eot delete mode 100644 content/.vuepress/public/fonts/fontawesome-webfont.svg delete mode 100644 content/.vuepress/public/fonts/fontawesome-webfont.ttf delete mode 100644 content/.vuepress/public/fonts/fontawesome-webfont.woff delete mode 100644 content/.vuepress/public/slate-logo.png delete mode 100644 content/.vuepress/public/slate-navbar.png delete mode 100644 content/.vuepress/scss/_fonts.scss delete mode 100644 content/.vuepress/scss/_variables.scss delete mode 100644 content/.vuepress/scss/fonts/FontAwesome.otf delete mode 100644 content/.vuepress/scss/fonts/fontawesome-webfont.eot delete mode 100644 content/.vuepress/scss/fonts/fontawesome-webfont.svg delete mode 100644 content/.vuepress/scss/fonts/fontawesome-webfont.ttf delete mode 100644 content/.vuepress/scss/fonts/fontawesome-webfont.woff delete mode 100644 content/.vuepress/scss/init/_normalize.scss delete mode 100644 content/.vuepress/scss/pages/_overview.scss delete mode 100644 content/.vuepress/theme/Layout.vue delete mode 100644 content/api/index.md delete mode 100644 content/build/index.md delete mode 100644 content/community/index.md delete mode 100644 content/contribute/index.md delete mode 100644 content/documentation.md delete mode 100644 content/glossary.md delete mode 100644 content/index.md delete mode 100644 content/overview/index.md delete mode 100644 content/resources/claimtrie.md delete mode 100644 content/resources/encrypt-lbrycrd.md delete mode 100644 content/resources/index.md delete mode 100644 content/resources/lbry-claimtrie.md delete mode 100644 content/resources/lbry.md delete mode 100644 content/resources/lbrycrd.md delete mode 100644 content/resources/pow.md delete mode 100644 content/resources/regtest-setup.md delete mode 100644 content/resources/repository-standards.md delete mode 100644 content/resources/schema.md delete mode 100644 content/resources/signing-claim.md delete mode 100644 content/resources/uri.md delete mode 100644 content/sitemap.md delete mode 100644 content/subscribe/index.md delete mode 100644 content/tour/index.md delete mode 100644 content/whitepaper.md create mode 100644 helpers/pa.js create mode 100644 helpers/slack.js create mode 100755 index.js delete mode 100644 npm-shrinkwrap.json mode change 100644 => 100755 package.json create mode 100755 public/apple-touch-icon.png create mode 100644 public/css/style.css create mode 100755 public/css/style.css.map rename {content/.vuepress/public => public}/favicon.ico (100%) rename {content/.vuepress/public => public}/favicon.svg (100%) create mode 100755 public/humans.txt rename {content/.vuepress => public}/media/images/background-a.jpg (100%) rename {content/.vuepress/public => public/media/images}/carlsagan2.jpg (100%) rename {content/.vuepress/public => public/media/images}/doge-meme.jpg (100%) rename {content/.vuepress => public}/media/images/grid.png (100%) rename {content/.vuepress/public => public/media/images}/lbry-green.png (100%) rename {content/.vuepress => public}/media/images/lbry-overview.png (100%) rename {content/.vuepress => public}/media/images/missing.png (100%) rename {content/.vuepress => public}/media/svg/anchor.svg (100%) rename {content/.vuepress => public}/media/svg/chat.svg (100%) rename {content/.vuepress => public}/media/svg/discord.svg (100%) rename {content/.vuepress => public}/media/svg/down.svg (100%) rename {content/.vuepress => public}/media/svg/flag.svg (100%) rename {content/.vuepress => public}/media/svg/keyboard.svg (100%) rename {content/.vuepress => public}/media/svg/logo--white.svg (100%) rename {content/.vuepress => public}/media/svg/logo.svg (100%) rename {content/.vuepress => public}/media/svg/monitor.svg (100%) rename {content/.vuepress => public}/media/svg/reddit.svg (100%) rename {content/.vuepress => public}/media/svg/slack.svg (100%) rename {content/.vuepress => public}/media/svg/text-logo--white.svg (100%) rename {content/.vuepress => public}/media/svg/text-logo.svg (100%) create mode 100755 public/scripts/app.js create mode 100755 public/scripts/vendor/zepto.js create mode 100755 public/type/karmilla/400.woff create mode 100755 public/type/karmilla/400.woff2 create mode 100755 public/type/karmilla/400i.woff create mode 100755 public/type/karmilla/700.woff create mode 100755 public/type/karmilla/700.woff2 create mode 100755 public/type/karmilla/700i.woff create mode 100755 public/type/playfair/400.woff create mode 100755 public/type/playfair/400.woff2 create mode 100755 public/type/playfair/400i.woff create mode 100755 public/type/playfair/400i.woff2 create mode 100755 public/type/playfair/700.woff create mode 100755 public/type/playfair/700.woff2 create mode 100755 public/type/playfair/700i.woff create mode 100755 public/type/playfair/700i.woff2 rename {content/.vuepress/scss => sass}/_layout.scss (96%) rename {content/.vuepress/scss => sass}/init/_base.scss (100%) rename {content/.vuepress/scss => sass}/init/_colors.scss (100%) rename {content/.vuepress/scss => sass}/init/_extends.scss (100%) rename {content/.vuepress/scss => sass}/init/_mixins.scss (100%) rename {content/.vuepress/scss => sass}/pages/_contributing.scss (100%) rename {content/.vuepress/scss => sass}/pages/_documentation.scss (100%) rename {content/.vuepress/scss => sass}/pages/_home.scss (100%) rename {content/.vuepress/scss => sass}/pages/_page.scss (97%) rename {content/.vuepress/scss => sass}/partials/_animation.scss (100%) create mode 100644 sass/partials/_ecosystem.scss create mode 100644 sass/partials/_email-subscribe.scss rename {content/.vuepress/scss => sass}/partials/_footer.scss (100%) create mode 100644 sass/partials/_github-feed.scss create mode 100644 sass/partials/_mission-statement.scss rename {content/.vuepress/scss => sass}/partials/_modal.scss (100%) rename {content/.vuepress/scss => sass}/partials/_navigation.scss (98%) create mode 100755 sass/style.scss rename {content/.vuepress/scss => sass}/type/_karla.scss (100%) mode change 100644 => 100755 server.js delete mode 100644 test/api.js create mode 100755 views/components/html.js create mode 100755 views/components/layout.js create mode 100755 views/pages/_404.js create mode 100755 views/pages/_error.js create mode 100644 views/pages/github-feed.js create mode 100755 views/pages/home.js create mode 100644 views/pages/overview.md create mode 100644 views/pages/page.js create mode 100644 views/pages/resources.js create mode 100644 views/partials/ecosystem-scripts.js create mode 100644 views/partials/ecosystem.js create mode 100644 views/partials/edit-link.js create mode 100644 views/partials/email-subscribe.js create mode 100755 views/partials/footer.js create mode 100644 views/partials/github-feed.js create mode 100755 views/partials/head.js create mode 100644 views/partials/mission-statement.js create mode 100755 views/partials/navigation.js create mode 100755 views/partials/noscript.js create mode 100755 views/show.js diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ecb7f29..cdd45e9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -16,4 +16,4 @@ Backend is handled by Node.js + Express. Currently all backend functionality is ### Frontend -[Vuepress](https://vuepress.vuejs.org/) generates static files based on the .vuepress folder and various markdown files in the root of the project. It automatically compiles JS and SCSS found in Vue components in .vuepress folder. \ No newline at end of file +[Vuepress](https://vuepress.vuejs.org/) generates static files based on the .vuepress folder and various markdown files in the root of the project. It automatically compiles JS and SCSS found in Vue components in .vuepress folder. diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 0d9d8a6..c0bfd6b --- a/README.md +++ b/README.md @@ -1,60 +1,56 @@ -# LBRY.tech Website +# LBRY.tech + +Technical documentation website for [the LBRY protocol](https://lbry.io) made with JavaScript. [![Build Status](https://travis-ci.org/lbryio/lbry.tech.svg?branch=master)](https://travis-ci.org/lbryio/lbry.tech) -Technical documentation website for [the LBRY protocol](https://lbry.io/) made with Javascript. + Notable tools used: -* [Vue.js](https://vuejs.org/) -* [Vuepress](https://vuepress.vuejs.org/) -* [Highlight.js](https://highlightjs.org/) +* [choo](https://choo.io) +* [fastify](https://www.fastify.io) ![Screenshot of LBRY.tech](https://spee.ch/f/lbry-tech-screenshot.png) + + ## Installation -This project is not designed to be installed directly. Continue reading below to learn how to use this project. +[Node](https://nodejs.org) (version >= 10) is required, so install that first. Then fork this repo, `cd` into it and run `npm i`. + + + +## Development + +`npm run watch` and visit [localhost:8080](http://localhost:8080) + + ## Usage -Visit [LBRY.tech](https://lbry.tech) for hosted version for this repository. +Visit [LBRY.tech](https://lbry.tech) to see this repo in production. -## Running from Source -### Prerequisities - -* [Node](https://nodejs.org/) (version >= 10) -* [Yarn](https://yarnpkg.com/) - -### Compiling - -``` bash -# clone git project -git clone https://github.com/lbryio/lbry.tech - -# install dependencies -yarn - -# serve with hot reload at localhost:8080 -yarn dev - -# build for production with minification & start express server -yarn start -``` ## Contributing -Contributions to this project are welcome, encouraged, and compensated. For more details, see [CONTRIBUTING.md](CONTRIBUTING.md) +Contributions to this project are welcome, encouraged, and compensated. For more details, see [CONTRIBUTING.md](CONTRIBUTING.md). + + ## License -This project is MIT licensed. For the full license, see [LICENSE](LICENSE) +This project is MIT licensed. For the full license, see [LICENSE](LICENSE). + + ## Security We take security seriously. Please contact [security@lbry.io](mailto:security@lbry.io) regarding any security issues. [Our PGP key is here](https://keybase.io/lbry/key.asc) if you need it. + + ## Contact -The primary contact for this project is [@kauffj](https://github.com/kauffj) +The primary contact for this project is [@netoperatorwibby](https://github.com/netoperatorwibby) diff --git a/client.js b/client.js new file mode 100755 index 0000000..e2c9d14 --- /dev/null +++ b/client.js @@ -0,0 +1,69 @@ +"use strict"; + + + +// P A C K A G E S + +const async = require("choo-async"); +const bundles = require("choo-bundles"); +const choo = require("choo"); +const data = require("choo-data"); +const devtools = require("choo-devtools"); +const ssr = require("choo-ssr"); + +// V A R I A B L E S + +const head = require("./views/partials/head"); +const html = require("./views/components/html"); +const layout = require("./views/components/layout"); +const noscript = require("./views/partials/noscript"); + + + +// P R O G R A M + +function main () { + const app = async(choo()); + + app.use(ssr()); + app.use(data()); + app.use(bundles()); + + if (process.env.NODE_ENV !== "production") app.use(devtools()); + + const page = content => (html( + ssr.head( + head(), + bundles.assets() + ), + ssr.body( + async.catch( + layout(content), + require("./views/pages/_error")(app) + ), + noscript(), + ssr.state(), + ) + )); + + app.route("/", page(require("./views/pages/home")(app))); + // app.route("/github-feed", page(require("./views/pages/github-feed")(app))); + app.route("/resources", page(require("./views/pages/resources")(app))); + app.route("/*", page(require("./views/pages/page")(app))); + + // app.route("/:page", page(require("./views/show")(app))); + // app.route("*", page(require("./views/pages/_404")(app))); + + return app; +} + +if (typeof window !== "undefined") { + const app = main(); + app.mount("html"); +} + + + +// E X P O R T + +module.exports = exports = main; diff --git a/content/.vuepress/config.js b/config.js similarity index 54% rename from content/.vuepress/config.js rename to config.js index d38c064..7feab66 100644 --- a/content/.vuepress/config.js +++ b/config.js @@ -1,15 +1,12 @@ -// .vuepress/config.js +"use strict"; + + + module.exports = exports = { - base: "/", - title: "LBRY.tech", - head: [ - ["meta", { name: "viewport", content: "initial-scale=1, viewport-fit=cover" }], - ["link", { rel: "mask-icon", href: "/favicon.svg", color: "#222" }] - ], - themeConfig: { + github: { repo: "lbryio/lbry.tech", docsBranch: "master/content", - editLinkText: "Edit this page on Github" + editLinkText: "Edit this page on GitHub" }, ga: "UA-60403362-1", markdown: { @@ -22,4 +19,4 @@ module.exports = exports = { } })) } -} +}; diff --git a/content/.vuepress/components/Ecosystem.vue b/content/.vuepress/components/Ecosystem.vue deleted file mode 100644 index 2cedf58..0000000 --- a/content/.vuepress/components/Ecosystem.vue +++ /dev/null @@ -1,913 +0,0 @@ - - - - - diff --git a/content/.vuepress/components/EditLink.vue b/content/.vuepress/components/EditLink.vue deleted file mode 100644 index d318e13..0000000 --- a/content/.vuepress/components/EditLink.vue +++ /dev/null @@ -1,36 +0,0 @@ - - - diff --git a/content/.vuepress/components/EmailSubscribe.vue b/content/.vuepress/components/EmailSubscribe.vue deleted file mode 100644 index 59250e3..0000000 --- a/content/.vuepress/components/EmailSubscribe.vue +++ /dev/null @@ -1,181 +0,0 @@ - - - - - diff --git a/content/.vuepress/components/EmailSubscribeLarge.vue b/content/.vuepress/components/EmailSubscribeLarge.vue deleted file mode 100644 index 2f1ce47..0000000 --- a/content/.vuepress/components/EmailSubscribeLarge.vue +++ /dev/null @@ -1,104 +0,0 @@ - - - - - diff --git a/content/.vuepress/components/FeatureLinks.vue b/content/.vuepress/components/FeatureLinks.vue deleted file mode 100644 index fc62fbe..0000000 --- a/content/.vuepress/components/FeatureLinks.vue +++ /dev/null @@ -1,110 +0,0 @@ - - - - - diff --git a/content/.vuepress/components/GithubFeed.vue b/content/.vuepress/components/GithubFeed.vue deleted file mode 100644 index 3482ec5..0000000 --- a/content/.vuepress/components/GithubFeed.vue +++ /dev/null @@ -1,340 +0,0 @@ - - - - - diff --git a/content/.vuepress/components/MissionStatement.vue b/content/.vuepress/components/MissionStatement.vue deleted file mode 100644 index 6d32f26..0000000 --- a/content/.vuepress/components/MissionStatement.vue +++ /dev/null @@ -1,35 +0,0 @@ - - - diff --git a/content/.vuepress/components/Sidebar.vue b/content/.vuepress/components/Sidebar.vue deleted file mode 100644 index 90c757d..0000000 --- a/content/.vuepress/components/Sidebar.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - - - \ No newline at end of file diff --git a/content/.vuepress/components/Sitemap.vue b/content/.vuepress/components/Sitemap.vue deleted file mode 100644 index c81d653..0000000 --- a/content/.vuepress/components/Sitemap.vue +++ /dev/null @@ -1,25 +0,0 @@ - - - diff --git a/content/.vuepress/components/Slate.vue b/content/.vuepress/components/Slate.vue deleted file mode 100644 index fac3d85..0000000 --- a/content/.vuepress/components/Slate.vue +++ /dev/null @@ -1,366 +0,0 @@ - - - - - diff --git a/content/.vuepress/components/Tour/Hook.vue b/content/.vuepress/components/Tour/Hook.vue deleted file mode 100644 index d9afe89..0000000 --- a/content/.vuepress/components/Tour/Hook.vue +++ /dev/null @@ -1,447 +0,0 @@ - - - - - diff --git a/content/.vuepress/components/Tour/Step1.vue b/content/.vuepress/components/Tour/Step1.vue deleted file mode 100644 index 2ddbf78..0000000 --- a/content/.vuepress/components/Tour/Step1.vue +++ /dev/null @@ -1,140 +0,0 @@ - - - diff --git a/content/.vuepress/components/Tour/Step2.vue b/content/.vuepress/components/Tour/Step2.vue deleted file mode 100644 index 727cf01..0000000 --- a/content/.vuepress/components/Tour/Step2.vue +++ /dev/null @@ -1,262 +0,0 @@ - - - diff --git a/content/.vuepress/components/Tour/Step3.vue b/content/.vuepress/components/Tour/Step3.vue deleted file mode 100644 index 33d5bbf..0000000 --- a/content/.vuepress/components/Tour/Step3.vue +++ /dev/null @@ -1,139 +0,0 @@ - - - diff --git a/content/.vuepress/event-bus.js b/content/.vuepress/event-bus.js deleted file mode 100644 index 2cf9835..0000000 --- a/content/.vuepress/event-bus.js +++ /dev/null @@ -1,4 +0,0 @@ -import Vue from "vue"; -const EventBus = new Vue(); - -export default EventBus; diff --git a/content/.vuepress/js/jquery.highlight.js b/content/.vuepress/js/jquery.highlight.js deleted file mode 100644 index 0c654a3..0000000 --- a/content/.vuepress/js/jquery.highlight.js +++ /dev/null @@ -1,109 +0,0 @@ -/* - * jQuery Highlight plugin - * - * Based on highlight v3 by Johann Burkard - * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html - * - * Code a little bit refactored and cleaned (in my humble opinion). - * Most important changes: - * - has an option to highlight only entire words (wordsOnly - false by default), - * - has an option to be case sensitive (caseSensitive - false by default) - * - highlight element tag and class names can be specified in options - * - * Usage: - * // wrap every occurrance of text 'lorem' in content - * // with (default options) - * $('#content').highlight('lorem'); - * - * // search for and highlight more terms at once - * // so you can save some time on traversing DOM - * $('#content').highlight(['lorem', 'ipsum']); - * $('#content').highlight('lorem ipsum'); - * - * // search only for entire word 'lorem' - * $('#content').highlight('lorem', { wordsOnly: true }); - * - * // don't ignore case during search of term 'lorem' - * $('#content').highlight('lorem', { caseSensitive: true }); - * - * // wrap every occurrance of term 'ipsum' in content - * // with - * $('#content').highlight('ipsum', { element: 'em', className: 'important' }); - * - * // remove default highlight - * $('#content').unhighlight(); - * - * // remove custom highlight - * $('#content').unhighlight({ element: 'em', className: 'important' }); - * - * - * Copyright (c) 2009 Bartek Szopka - * - * Licensed under MIT license. - * - */ - -jQuery.extend({ - highlight: function (node, re, nodeName, className) { - if (node.nodeType === 3) { - var match = node.data.match(re); - if (match) { - var highlight = document.createElement(nodeName || 'span'); - highlight.className = className || 'highlight'; - var wordNode = node.splitText(match.index); - wordNode.splitText(match[0].length); - var wordClone = wordNode.cloneNode(true); - highlight.appendChild(wordClone); - wordNode.parentNode.replaceChild(highlight, wordNode); - return 1; //skip added node in parent - } - } else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children - !/(script|style)/i.test(node.tagName) && // ignore script and style nodes - !(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted - for (var i = 0; i < node.childNodes.length; i++) { - i += jQuery.highlight(node.childNodes[i], re, nodeName, className); - } - } - return 0; - } -}); - -jQuery.fn.unhighlight = function (options) { - var settings = { className: 'highlight', element: 'span' }; - jQuery.extend(settings, options); - - return this.find(settings.element + "." + settings.className).each(function () { - var parent = this.parentNode; - parent.replaceChild(this.firstChild, this); - parent.normalize(); - }).end(); -}; - -jQuery.fn.highlight = function (words, options) { - var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; - jQuery.extend(settings, options); - - if (words.constructor === String) { - words = [words]; - } - words = jQuery.grep(words, function(word, i){ - return word != ''; - }); - words = jQuery.map(words, function(word, i) { - return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); - }); - if (words.length == 0) { return this; }; - - var flag = settings.caseSensitive ? "" : "i"; - var pattern = "(" + words.join("|") + ")"; - if (settings.wordsOnly) { - pattern = "\\b" + pattern + "\\b"; - } - var re = new RegExp(pattern, flag); - - return this.each(function () { - jQuery.highlight(this, re, settings.element, settings.className); - }); -}; - - diff --git a/content/.vuepress/public/api.md b/content/.vuepress/public/api.md deleted file mode 100644 index 932466d..0000000 --- a/content/.vuepress/public/api.md +++ /dev/null @@ -1,1656 +0,0 @@ -::: api__content__body -# API Reference - -At LBRY, we utilize JSON-RPC for our API. -::: - -::: api__content__example -``` -This is a work-in-progress! -``` -::: - - - -::: api__content__body -## blob_announce - -Announce blobs to the DHT. -::: - -::: api__content__example -Returns: - -``` -(bool) true if successful -``` - -Arguments: - -| Parameter | Description | -|:------------|:--------------------------------------------------------------------------| -| blob_hash | (str) announce a blob, specified by blob hash | -| sd_hash | (str) announce all blobs associated with `sd_hash` and the sd hash itself | -| stream_hash | (str) announce all blobs associated with `stream_hash` | -::: - - - -::: api__content__body -## blob_availability - -Get blob availability. -::: - -::: api__content__example -Returns: - -``` -(dict) { - "is_available": - "reachable_peers": [":"], - "unreachable_peers": [":"] -} -``` - -Arguments: - -| Parameter | Description | -|:---------------|:-----------------------------------------------------------| -| blob_hash | (str) check availability for this blob hash | -| blob_timeout | (int) how long to try downloading from a peer | -| search_timeout | (int) how long to search for peers for the blob in the dht | -::: - - - -::: api__content__body -## blob_delete - -Delete a blob. -::: - -::: api__content__example -Returns: - -``` -(str) Success/fail message -``` - -Arguments: - -| Parameter | Description | -|:------------|:--------------------------------------| -| blob_hash | (str) blob hash of the blob to delete | -::: - - - -::: api__content__body -## blob_get - -Download and return a blob. -::: - -::: api__content__example -Returns: - -``` -(str) Success/Fail message or (dict) decoded data -``` - -Arguments: - -| Parameter | Description | -|:---------------------|:-------------------------------------------------------------------------------------------------------------------| -| blob_hash *required* | (str) blob hash of the blob to get | -| encoding | (str) by default no attempt at decoding is made, can be set to one of the following decoders: "json" | -| payment_rate_manager | (str) if not given the default payment rate manager will be used. Supported alternative rate managers: "only-free" | -| timeout | (int) timeout in number of seconds | -::: - - - -::: api__content__body -## blob_list - -Returns blob hashes. If not given filters, returns all blobs known by the blob manager. -::: - -::: api__content__example -Returns: - -``` -(list) List of blob hashes -``` - -Arguments: - -| Parameter | Description | -|:------------|:--------------------------------------| -| finished | (bool) only return finished blobs | -| needed | (bool) only return needed blobs | -| page | (int) page of results to return | -| page_size | (int) results page size | -| sd_hash | (str) filter blobs by sd hash | -| stream_hash | (str) filter blobs by stream hash | -| uri | (str) filter blobs by stream in a uri | -::: - - - -::: api__content__body -## blob_reflect - -Reflects specified blobs. -::: - -::: api__content__example -Returns: - -``` -(list) reflected blob hashes -``` - -Arguments: - -| Parameter | Description | -|:-----------------|:------------------------| -| reflector_server | (str) reflector address | -::: - - - -::: api__content__body -## blob_reflect_all - -Reflects all saved blobs. -::: - -::: api__content__example -Returns: - -``` -(bool) true if successful -``` -::: - - - -::: api__content__body -## block_show - -Get contents of a block. -::: - -::: api__content__example -Returns: - -``` -(dict) Requested block -``` - -Arguments: - -| Parameter | Description | -|:---------------------|:-------------------------------------| -| blockhash *required* | (str) hash of the block to look up | -| height *required* | (int) height of the block to look up | -::: - - - -::: api__content__body -## channel_export - -Export serialized channel signing information for a given certificate claim id. -::: - -::: api__content__example -Returns: - -``` -(str) Serialized certificate information -``` - -Arguments: - -| Parameter | Description | -|:--------------------|:-------------------------------------------| -| claim_id *required* | (str) Claim ID to export information about | -::: - - - -::: api__content__body -## channel_import - -Import serialized channel signing information (to allow signing new claims to the channel). -::: - -::: api__content__example -Returns: - -``` -(dict) Result dictionary -``` - -Arguments: - -| Parameter | Description | -|:---------------------------------------|:-----------------------| -| serialized_certificate_info *required* | (str) certificate info | -::: - - - -::: api__content__body -## channel_list - -Get certificate claim infos for channels that can be published to. -::: - -::: api__content__example -Returns: - -``` -(list) ClaimDict, includes "is_mine" field to indicate if the certificate claim is in the wallet. -``` -::: - - - -::: api__content__body -## channel_new - -Generate a publisher key and create a new "@" prefixed certificate claim. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary containing result of the claim - -{ - "claim_id": (str) claim ID of the resulting claim - "fee": (float) fee paid for the claim transaction - "nout": (int) nout of the resulting claim - "tx": (str) hex encoded transaction - "txid": (str) txid of resulting claim -} -``` - -Arguments: - -| Parameter | Description | -|:------------------------|:--------------------------------------------| -| amount *required* | (float) bid amount on the channel | -| channel_name *required* | (str) name of the channel prefixed with "@" | -::: - - - -::: api__content__body -## claim_abandon - -Abandon a name and reclaim credits from the claim. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary containing result of the claim - -{ - "fee": (float) fee paid for the transaction - "txid": (str) txid of resulting transaction -} -``` - -Arguments: - -| Parameter | Description | -|:------------|:-----------------------------------| -| claim_id | (str) id of the claim to abandon | -| nout | (int) nout of the claim to abandon | -| txid | (str) txid of the claim to abandon | -::: - - - -::: api__content__body -## claim_list - -List current claims and information about them for a given name. -::: - -::: api__content__example -Returns: - -``` -(dict) State of claims assigned for the name - -{ - "claims": (list) list of claims for the name - [{ - "amount": (float) amount assigned to the claim - "claim_id": (str) claim ID of the claim - "effective_amount": (float) total amount assigned to the claim, including supports - "height": (int) height of block containing the claim - "nout": (int) nout of the claim - "permanent_url": (str) permanent url of the claim - "supports": (list) a list of supports attached to the claim - "txid": (str) txid of the claim - "value": (str) the value of the claim - }], - "last_takeover_height": (int) the height of last takeover for the name - "supports_without_claims": (list) supports without any claims attached to them -} -``` - -Arguments: - -| Parameter | Description | -|:----------------|:-------------------------------------------| -| name *required* | (str) name of the claim to list info about | -::: - - - -::: api__content__body -## claim_list_by_channel - -Get paginated claims in a channel specified by a channel uri. -::: - -::: api__content__example -Returns: - -``` -{ - resolved channel uri: { - If there was an error: - "error": (str) error message - - "claims_in_channel": the total number of results for the channel - - If a page of results was requested: - "returned_page": page number returned - "claims_in_channel": [{ - "absolute_channel_position": (int) claim index number in sorted list of - claims which assert to be part of the - channel - "address": (str) claim address - "amount": (float) claim amount - "claim_id": (str) claim id - "claim_sequence": (int) claim sequence number - "decoded_claim": (bool) whether or not the claim value was decoded - "depth": (int) claim depth - "effective_amount": (float) claim amount including supports - "has_signature": (bool) included if decoded_claim - "height": (int) claim height - "name": (str) claim name - "nout": (str) claim nout - "signature_is_valid": (bool), included if has_signature - "supports": (list) list of supports [{ - "amount": (float) amount - "nout": (int) nout - "txid": (str) txid - }] - "txid": (str) claim txid - "value": ClaimDict if decoded, otherwise hex string - }] - } -} -``` - -Arguments: - -| Parameter | Description | -|:---------------|:-------------------------------------------------------------------------------------------| -| page | (int) which page of results to return where page 1 is the first page, defaults to no pages | -| page_size | (int) number of results in a page, default of 10 | -| uri *required* | (str) uri of the channel | -| uris | (list) uris of the channel | -::: - - - -::: api__content__body -## claim_list_mine - -List my name claims. -::: - -::: api__content__example -Returns: - -``` -(list) List of name claims owned by user - -[{ - "address": (str) address that owns the claim - "amount": (float) amount assigned to the claim - "blocks_to_expiration": (int) number of blocks until it expires - "category": (str) "claim", "update", or "support" - "claim_id": (str) claim ID of the claim - "confirmations": (int) number of blocks of confirmations for the claim - "expiration_height": (int) the block height which the claim will expire - "expired": (bool) true if expired, false otherwise - "height": (int) height of the block containing the claim - "is_spent": (bool) true if claim is abandoned, false otherwise - "name": (str) name of the claim - "nout": (int) nout of the claim - "permanent_url": (str) permanent url of the claim - "txid": (str) txid of the claim - "value": (str) value of the claim -}] -``` -::: - - - -::: api__content__body -## claim_new_support - -Support a name claim. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary containing result of the claim - -{ - fee: (float) fee paid for the transaction - nout: (int) nout of the resulting support claim - txid: (str) txid of resulting support claim -} -``` - -Arguments: - -| Parameter | Description | -|:--------------------|:-----------------------------------| -| amount *required* | (float) amount of support | -| claim_id *required* | (str) id of the claim to support | -| name *required* | (str) name of the claim to support | -::: - - - -::: api__content__body -## claim_renew - -Renew claim(s) or support(s). -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary where key is the the original claim's outpoint and value is the result of the renewal - -{ - "outpoint": { - "claim_id": (str) claim ID of the resulting claim - "fee": (float) fee paid for the claim transaction - "nout": (int) nout of the resulting claim - "tx": (str) hex encoded transaction - "txid": (str) txid of resulting claim - } -} -``` - -Arguments: - -| Parameter | Description | -|:--------------------|:------------------------------------------------------------| -| height *required* | (str) update claims expiring before or at this block height | -| outpoint *required* | (str) outpoint of the claim to renew | -::: - - - -::: api__content__body -## claim_send_to_address - -Send a name claim to an address. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary containing result of the claim - -{ - "claim_id": (str) claim ID of the resulting claim - "fee": (float) fee paid for the claim transaction - "nout": (int) nout of the resulting claim - "tx": (str) hex encoded transaction - "txid": (str) txid of resulting claim -} -``` - -Arguments: - -| Parameter | Description | -|:--------------------|:---------------------------------------------------------------------------------------| -| address *required* | (str) address to send the claim to | -| amount | (int) amount of credits to claim name for, defaults to the current amount on the claim | -| claim_id *required* | (str) claim id to send | -::: - - - -::: api__content__body -## claim_show - -Resolve claim info from nout/txid or with claim ID. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary containing claim info as below - -{ - "amount": (float) amount of claim - "claim_id": (str) claim ID of claim - "height" : (int) height of claim takeover - "nout": (int) nout of claim - "supports": (list) list of supports associated with claim - "txid": (str) txid of claim - "value": (str) value of claim -} - -If claim cannot be resolved, dictionary as below will be returned - -{ - "error": (str) reason for error -} -``` - -Arguments: - -| Parameter | Description | -|:------------|:-----------------------------------------------------------------| -| claim_id | (str) look for claim with this claim id | -| nout | (int) look for claim with this nout, txid must also be specified | -| txid | (str) look for claim with this txid, nout must also be specified | -::: - - - -::: api__content__body -## cli_test_command - -This command is only for testing the CLI argument parsing. -::: - -::: api__content__example -Returns: - -``` -pos args -``` - -Arguments: - -| Parameter | Description | -|:-------------------|:--------------| -| a_arg | a arg | -| b_arg | b arg | -| pos_arg *required* | pos arg | -| pos_args | pos args | -| pos_arg2 | pos arg 2 | -| pos_arg3 | pos arg 3 | -::: - - - -::: api__content__body -## commands - -Return a list of available commands. -::: - -::: api__content__example -Returns: - -``` -(list) list of available commands -``` -::: - - - -::: api__content__body -## daemon_stop - -Stop lbrynet-daemon. -::: - -::: api__content__example -Returns: - -``` -(string) Shutdown message -``` -::: - - - -::: api__content__body -## file_delete - -Delete a LBRY file. -::: - -::: api__content__example -Returns: - -``` -(bool) true if deletion was successful -``` - -Arguments: - -| Parameter | Description | -|:-------------------------|:----------------------------------------------------------------------------------------------------------------------| -| channel_claim_id | (str) delete by file channel claim id | -| channel_name | (str) delete by file channel claim name | -| claim_id | (str) delete by file claim id | -| claim_name | (str) delete by file claim name | -| delete_all | (bool) if there are multiple matching files, allow the deletion of multiple files. Otherwise, do not delete anything. | -| delete_from_download_dir | (bool) delete file from download directory, instead of just deleting blobs | -| file_name | (str) delete by file name in downloads folder | -| nout | (int) delete by file claim nout | -| rowid | (int) delete by file row id | -| sd_hash | (str) delete by file sd hash | -| stream_hash | (str) delete by file stream hash | -| txid | (str) delete by file claim txid | -::: - - - -::: api__content__body -## file_list - -List files limited by optional filters. -::: - -::: api__content__example -Returns: - -``` -(list) List of files - -[{ - "blobs_completed": (int) num_completed, None if full_status is false - "blobs_in_stream": (int) None if full_status is false - "channel_claim_id": (str) None if full_status is false or if claim is not found or signed - "channel_name": (str) None if full_status is false or if claim is not found or signed - "claim_id": (str) None if full_status is false or if claim is not found - "claim_name": (str) None if full_status is false or if claim is not found - "completed": (bool) true if download is completed - "download_directory": (str) download directory - "download_path": (str) download path of file - "file_name": (str) name of file - "key": (str) key attached to file - "metadata": (dict) None if full_status is false or if claim is not found - "mime_type": (str) mime type of file - "nout": (int) None if full_status is false or if claim is not found - "outpoint": (str) None if full_status is false or if claim is not found - "points_paid": (float) credit paid to download file - "sd_hash": (str) sd hash of file - "status": (str) downloader status, None if full_status is false - "stopped": (bool) true if download is stopped - "stream_hash": (str) stream hash of file - "stream_name": (str) stream name - "suggested_file_name": (str) suggested file name - "total_bytes": (int) file size in bytes, None if full_status is false - "txid": (str) None if full_status is false or if claim is not found - "written_bytes": (int) written size in bytes -}] -``` - -Arguments: - -| Parameter | Description | -|:-----------------|:-----------------------------------------------------------------------------------------------------------------| -| channel_claim_id | (str) get file with matching channel claim id | -| channel_name | (str) get file with matching channel name | -| claim_id | (str) get file with matching claim id | -| claim_name | (str) get file with matching claim name | -| file_name | (str) get file with matching file name in the downloads folder | -| full_status | (bool) full status, populate the "message" and "size" fields | -| nout | (int) get file with matching claim nout | -| outpoint | (str) get file with matching claim outpoint | -| rowid | (int) get file with matching row id | -| sd_hash | (str) get file with matching sd hash | -| sort | (str) sort by any property, like "file_name" or "metadata.author"; to specify direction append ",asc" or ",desc" | -| stream_hash | (str) get file with matching stream hash | -| txid | (str) get file with matching claim txid | -::: - - - -::: api__content__body -## file_reflect - -Reflect all the blobs in a file matching the filter criteria. -::: - -::: api__content__example -Returns: - -``` -(list) list of blobs reflected -``` - -Arguments: - -| Parameter | Description | -|:------------|:-------------------------------------------------------------------------------------| -| file_name | (str) get file with matching file name in the downloads folder | -| reflector | (str) reflector server, ip address or url by default choose a server from the config | -| rowid | (int) get file with matching row id | -| sd_hash | (str) get file with matching sd hash | -| stream_hash | (str) get file with matching stream hash | -::: - - - -::: api__content__body -## file_set_status - -Start or stop downloading a file. -::: - -::: api__content__example -Returns: - -``` -(str) Confirmation message -``` - -Arguments: - -| Parameter | Description | -|:------------------|:-------------------------------------------------------------------------| -| file_name | (str) set status of file with matching file name in the downloads folder | -| rowid | (int) set status of file with matching row id | -| sd_hash | (str) set status of file with matching sd hash | -| status *required* | (str) one of "start" or "stop" | -| stream_hash | (str) set status of file with matching stream hash | -::: - - - -::: api__content__body -## get - -Download stream from a LBRY name. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary containing information about the stream - -{ - "blobs_completed": (int) num_completed, None if `full_status` is false - "blobs_in_stream": (int) None if `full_status` is false - "channel_claim_id": (str) None if claim is not signed - "channel_name": (str) None if claim is not signed - "claim_id": (str) claim id - "claim_name": (str) claim name - "completed": (bool) true if download is completed - "download_directory": (str) download directory - "download_path": (str) download path of file - "key": (str) key attached to file - "file_name": (str) name of file - "metadata": (dict) claim metadata - "mime_type": (str) mime type of file - "nout": (int) claim nout - "outpoint": (str) claim outpoint string - "points_paid": (float) credit paid to download file - "sd_hash": (str) sd hash of file - "status": (str) downloader status, None if `full_status` is false - "stopped": (bool) true if download is stopped - "stream_hash": (str) stream hash of file - "stream_name": (str) stream name - "suggested_file_name": (str) suggested file name - "total_bytes": (int) file size in bytes, None if `full_status` is false - "txid": (str) claim txid - "written_bytes": (int) written size in bytes -} -``` - -Arguments: - -| Parameter | Description | -|:------------|:---------------------------------------------| -| file_name | (str) specified name for the downloaded file | -| timeout | (int) download timeout in number of seconds | -| uri | (str) uri of the content to download | -::: - - - -::: api__content__body -## help - -Return a useful message for an API command. -::: - -::: api__content__example -Returns: - -``` -(str) Help message -``` - -Arguments: - -| Parameter | Description | -|:------------|:--------------------------------------------| -| command | (str) command to retrieve documentation for | -::: - - - -::: api__content__body -## peer_list - -Get peers for blob hash. -::: - -::: api__content__example -Returns: - -``` -(list) List of contact dictionaries { "host": , "port": , "node_id": } -``` - -Arguments: - -| Parameter | Description | -|:---------------------|:----------------------------------------------| -| blob_hash *required* | (str) find available peers for this blob hash | -| timeout | (int) peer search timeout in seconds | -::: - - - -::: api__content__body -## peer_ping - -Find and ping a peer by node id. -::: - -::: api__content__example -Returns: - -``` -(str) pong, or {"error": } if an error is encountered -``` -::: - - - -::: api__content__body -## publish - -Make a new name claim and publish associated data to lbrynet, update over existing claim if user already has a claim for name. - -Fields required in the final Metadata are: -- author -- description -- language -- license -- nsfw -- title - -Metadata can be set by either using the metadata argument or by setting individual arguments fee, title, description, author, language, license, license_url, thumbnail, preview, nsfw, or sources. Individual arguments will overwrite the fields specified in metadata argument. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary containing result of the claim - -{ - "claim_id": (str) claim ID of the resulting claim - "fee": (decimal) fee paid for the claim transaction - "nout": (int) nout of the resulting claim - "tx": (str) hex encoded transaction - "txid": (str) txid of resulting claim -} -``` - -Arguments: - -| Parameter | Description | -|:----------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| author | (str) author of the publication | -| bid *required* | (decimal) amount to back the claim | -| channel_name | (str) name of the publisher channel name in the wallet | -| channel_id | (str) claim id of the publisher channel, does not check for channel claim being in the wallet. This allows publishing to a channel where only the certificate private key is in the wallet. | -| claim_address | (str) address where the claim is sent to, if not specified new address will automatically be created | -| description | (str) description of the publication | -| fee | (dict) Dictionary representing key fee to download content: {"currency": currency_symbol, "amount": decimal, "address": str, optional } supported currencies: LBC, USD, BTCIf an address is not provided a new one will be automatically generated. Default fee is zero. | -| file_path | (str) path to file to be associated with name. If provided, a lbry stream of this file will be used in "sources". If no path is given but a sources dict is provided, it will be used. If neither are provided, an error is raised. | -| language | (str) language of the publication | -| license | (str) publication license | -| license_url | (str) publication license url | -| metadata | (dict) ClaimDict to associate with the claim. | -| name *required* | (str) name of the content | -| nsfw | (bool) title of the publication | -| preview | (str) preview url | -| sources | (str) { "lbry_sd_hash": sd_hash } specifies sd hash of file | -| thumbnail | (str) thumbnail url | -| title | (str) title of the publication | -::: - - - -::: api__content__body -## report_bug - -Report a bug to Slack. -::: - -::: api__content__example -Returns: - -``` -(bool) true if successful -``` - -Arguments: - -| Parameter | Description | -|:-------------------|:-----------------------------| -| message *required* | (str) Description of the bug | -::: - - - -::: api__content__body -## resolve - -Resolve given LBRY URIs. -::: - -::: api__content__example -Returns: - -``` -Dictionary of results, keyed by uri - -"": { - If a resolution error occurs: - "error": Error message - - If the uri resolves to a channel or a claim in a channel: - "certificate": { - "address": (str) claim address - "amount": (float) claim amount - "claim_id": (str) claim id - "claim_sequence": (int) claim sequence number - "decoded_claim": (bool) whether or not the claim value was decoded - "depth": (int) claim depth - "effective_amount": (float) claim amount including supports - "has_signature": (bool) included if decoded_claim - "height": (int) claim height - "name": (str) claim name - "nout": (str) claim nout - "permanent_url": (str) permanent url of the certificate claim - "signature_is_valid": (bool), included if has_signature - "supports: (list) list of supports [{ - "amount": (float) amount - "nout": (int) nout - "txid": (str) txid - }] - "txid": (str) claim txid - "value": ClaimDict if decoded, otherwise hex string - } - - If the uri resolves to a channel: - "claims_in_channel": (int) number of claims in the channel, - - If the uri resolves to a claim: - "claim": { - "address": (str) claim address - "amount": (float) claim amount - "channel_name": (str) channel name if claim is in a channel - "claim_id": (str) claim id - "claim_sequence": (int) claim sequence number - "decoded_claim": (bool) whether or not the claim value was decoded - "depth": (int) claim depth - "effective_amount": (float) claim amount including supports - "has_signature": (bool) included if decoded_claim - "height": (int) claim height - "name": (str) claim name - "nout": (str) claim nout - "permanent_url": (str) permanent url of the claim - "signature_is_valid": (bool), included if has_signature - "supports: (list) list of supports [{ - "amount": (float) amount - "nout": (int) nout - "txid": (str) txid - }] - "txid": (str) claim txid - "value": ClaimDict if decoded, otherwise hex string - } -} -``` - -Arguments: - -| Parameter | Description | -|:---------------|:--------------------------------------| -| force | (bool) force refresh and ignore cache | -| uri *required* | (str) uri to resolve | -| uris | (list) uris to resolve | -::: - - - -::: api__content__body -## resolve_name - -Resolve stream info from a LBRY name. -::: - -::: api__content__example -Returns: - -``` -(dict) Metadata dictionary from name claim, None if the name is not resolvable -``` - -Arguments: - -| Parameter | Description | -|:----------------|:--------------------------------------------| -| force | (bool) force refresh and do not check cache | -| name *required* | (str) the name to resolve | -::: - - - -::: api__content__body -## routing_table_get - -Get DHT routing information. -::: - -::: api__content__example -Returns: - -``` -(dict) dictionary containing routing and contact information - -{ - "buckets": { - : [{ - "address": (str) peer address - "blobs": (list) blob hashes announced by peer - "node_id": (str) peer node id - "port": (int) peer udp port - }] - } - "blob_hashes": (list) all of the blob hashes stored by peers in the list of buckets - "contacts": (list) contact node ids - "node_id": (str) the local dht node id -} -``` -::: - - - -::: api__content__body -## settings_get - -Get daemon settings. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary of daemon settings -See ADJUSTABLE_SETTINGS in lbrynet/conf.py for full list of settings -``` -::: - - - -::: api__content__body -## settings_set - -Set daemon settings. -::: - -::: api__content__example -Returns: - -``` -(dict) Updated dictionary of daemon settings -``` - -Arguments: - -| Parameter | Description | -|:------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| auto_renew_claim_height_delta | (int) 0 claims set to expire within this many blocks will be automatically renewed after startup (if set to 0, renews will not be made automatically) | -| cache_time | (int) 150 | -| data_rate | (float) 0.0001 | -| disable_max_key_fee | (bool) False | -| download_directory | (str) path of download directory | -| download_timeout | (int) 180 | -| max_key_fee | (dict) maximum key fee for downloads, in the format: { "currency": , "amount": }. In the CLI, it must be an escaped JSON stringSupported currency symbols: LBC, USD, BTC | -| peer_port | (int) 3333 | -| peer_search_timeout | (int) 3 | -| reflect_uploads | (bool) True | -| run_reflector_server | (bool) False | -| sd_download_timeout | (int) 3 | -| share_usage_data | (bool) True | -| use_upnp | (bool) True | -::: - - - -::: api__content__body -## status - -Get daemon status. -::: - -::: api__content__example -Returns: - -``` -(dict) lbrynet-daemon status - -{ - "blockchain_status": { - "best_blockhash": block hash of most recent block - "blocks": local blockchain height - "blocks_behind": remote_height - local_height - } - "connection_status": { - "code": connection status code, - "message": connection status message - } - "installation_id": installation id, base58 - "is_first_run": bool - "is_running": bool - "lbry_id": lbry peer id, base58 - "startup_status": { - "code": status code, - "message": status message - } - "wallet_is_encrypted": bool - - If given the session status option: - - "session_status": { - "announce_queue_size": number of blobs currently queued to be announced - "managed_blobs": count of blobs in the blob manager - "managed_streams": count of streams in the file manager - "should_announce_blobs": number of blobs that should be announced - } -} -``` - -Arguments: - -| Parameter | Description | -|:---------------|:-----------------------------------------| -| session_status | (bool) include session status in results | -::: - - - -::: api__content__body -## stream_availability - -Get stream availability for lbry uri. -::: - -::: api__content__example -Returns: - -``` -(dict) { - "did_decode": - "did_resolve": - "error": | error message - "head_blob_availability": see `blob_availability` - "head_blob_hash": - "is_available": - "is_stream": - "num_blobs_in_stream": - "sd_blob_availability": see `blob_availability` - "sd_hash": - "upnp_redirect_is_set": - "use_upnp": -} -``` - -Arguments: - -| Parameter | Description | -|:---------------|:-----------------------------------------------------------| -| blob_timeout | (int) how long to try downloading from a peer | -| search_timeout | (int) how long to search for peers for the blob in the dht | -| uri *required* | (str) check availability for this uri | -::: - - - -::: api__content__body -## stream_cost_estimate - -Get estimated cost for a lbry stream. -::: - -::: api__content__example -Returns: - -``` -(float) Estimated cost in lbry credits, returns None if uri is not resolvable -``` - -Arguments: - -| Parameter | Description | -|:---------------|:--------------------------------------------------------------------------| -| size | (float) stream size in bytes. If provided an sd blob won't be downloaded. | -| uri *required* | (str) uri to use | -::: - - - -::: api__content__body -## transaction_list - -List transactions belonging to wallet. -::: - -::: api__content__example -Returns: - -``` -(list) List of transactions - -{ - "abandon_info": (list) abandon info if in txn [{ - "address": (str) address of abandoned claim - "amount": (float) claim amount - "balance_delta": (float) returned amount - "claim_id": (str) claim id - "claim_name": (str) claim name - "nout": (int) nout - }] - "claim_info": (list) claim info if in txn [{ - "address": (str) address of claim - "amount": (float) claim amount - "balance_delta": (float) bid amount - "claim_id": (str) claim id - "claim_name": (str) claim name - "nout": (int) nout - }] - "confirmations": (int) number of confirmations for the txn - "date": (str) date and time of txn - "fee": (float) txn fee - "support_info": (list) support info if in txn [{ - "address": (str) address of support - "amount": (float) support amount - "balance_delta": (float) support amount - "claim_id": (str) claim id - "claim_name": (str) claim name - "is_tip": (bool) - "nout": (int) nout - }] - "timestamp": (int) timestamp - "txid": (str) txn id - "update_info": (list) update info if in txn [{ - "address": (str) address of claim - "amount": (float) absolute amount - "balance_delta": (float) credited/debited - "claim_id": (str) claim id - "claim_name": (str) claim name - "nout": (int) nout - }] - "value": (float) value of txn -} -``` -::: - - - -::: api__content__body -## transaction_show - -Get a decoded transaction from a txid. -::: - -::: api__content__example -Returns: - -``` -(dict) JSON formatted transaction -``` - -Arguments: - -| Parameter | Description | -|:----------------|:------------------------------| -| txid *required* | (str) txid of the transaction | -::: - - - -::: api__content__body -## utxo_list - -List unspent transaction outputs. -::: - -::: api__content__example -Returns: - -``` -(list) List of unspent transaction outputs (UTXOs) - -[ - { - "address": (str) the output address - "amount": (float) unspent amount - "height": (int) block height - "is_claim": (bool) is the tx a claim - "is_coinbase": (bool) is the tx a coinbase tx - "is_support": (bool) is the tx a support - "is_update": (bool) is the tx an update - "nout": (int) nout of the output - "txid": (str) txid of the output - } - ... -] -``` -::: - - - -::: api__content__body -## version - -Get lbry version information. -::: - -::: api__content__example -Returns: - -``` -(dict) Dictionary of lbry version information - -{ - "build": (str) build type (e.g. "dev", "rc", "release") - "ip": (str) remote ip, if available - "lbrynet_version": (str) lbrynet_version - "lbryschema_version": (str) lbryschema_version - "lbryum_version": (str) lbryum_version - "os_release": (str) os release string - "os_system": (str) os name - "platform": (str) platform string - "processor": (str) processor type - "python_version": (str) python version -} -``` -::: - - - -::: api__content__body -## wallet_balance - -Return the balance of the wallet. -::: - -::: api__content__example -Returns: - -``` -(float) amount of lbry credits in wallet -``` - -Arguments: - -| Parameter | Description | -|:--------------------|:------------------------------------------------------------------| -| address | (str) If provided only the balance for this address will be given | -| include_unconfirmed | (bool) Include unconfirmed | -::: - - - -::: api__content__body -## wallet_decrypt - -Decrypt an encrypted wallet, this will remove the wallet password. -::: - -::: api__content__example -Returns: - -``` -(bool) true if wallet is decrypted, otherwise false -``` -::: - - - -::: api__content__body -## wallet_encrypt - -Encrypt a wallet with a password, if the wallet is already encrypted this will update -the password. -::: - -::: api__content__example -Returns: - -``` -(bool) true if wallet is decrypted, otherwise false -``` - -Arguments: - -| Parameter | Description | -|:------------------------|:-------------------------------------------------------| -| new_password *required* | (str) password string to be used for encrypting wallet | -::: - - - -::: api__content__body -## wallet_is_address_mine - -Checks if an address is associated with the current wallet. -::: - -::: api__content__example -Returns: - -``` -(bool) true, if address is associated with current wallet -``` - -Arguments: - -| Parameter | Description | -|:-------------------|:-----------------------| -| address *required* | (str) address to check | -::: - - - -::: api__content__body -## wallet_list - -List wallet addresses. -::: - -::: api__content__example -Returns: - -``` -List of wallet addresses -``` -::: - - - -::: api__content__body -## wallet_new_address - -Generate a new wallet address. -::: - -::: api__content__example -Returns: - -``` -(str) New wallet address in base58 -``` -::: - - - -::: api__content__body -## wallet_prefill_addresses - -Create new addresses, each containing `amount` credits. -::: - -::: api__content__example -Returns: - -``` -(dict) the resulting transaction -``` - -Arguments: - -| Parameter | Description | -|:-------------------------|:---------------------------------------| -| amount *required* | (float) initial amount in each address | -| no_broadcast | (bool) whether to broadcast or not | -| num_addresses *required* | (int) num of addresses to create | -::: - - - -::: api__content__body -## wallet_public_key - -Get public key from wallet address. -::: - -::: api__content__example -Returns: - -``` -(list) list of public keys associated with address. Could contain more than one public key if multisig. -``` - -Arguments: - -| Parameter | Description | -|:-------------------|:----------------------------------------------| -| address *required* | (str) address for which to get the public key | -::: - - - -::: api__content__body -## wallet_send - -Send credits. If given an address, send credits to it. If given a claim id, send a tip to the owner of a claim specified by uri. A tip is a claim support where the recipient of the support is the claim address for the claim being supported. -::: - -::: api__content__example -Returns: - -``` -If sending to an address: -(bool) true if payment successfully scheduled - -If sending a claim tip: -(dict) Dictionary containing the result of the support - -{ - "fee": (float) fee paid for the transaction - "nout": (int) nout of the resulting support claim - "txid": (str) txid of resulting support claim -} -``` - -Arguments: - -| Parameter | Description | -|:--------------------|:------------------------------------------| -| address *required* | (str) address to send credits to | -| amount *required* | (float) amount of credit to send | -| claim_id *required* | (float) claim id of the claim to send tip | -::: - - - -::: api__content__body -## wallet_unlock - -Unlock an encrypted wallet. -::: - -::: api__content__example -Returns: - -``` -(bool) true if wallet is unlocked, otherwise false -``` - -Arguments: - -| Parameter | Description | -|:--------------------|:------------------------------------| -| password *required* | (str) password for unlocking wallet | -::: - - - -::: api__content__body -## wallet_unused_address - -Return an address containing no balance, will create a new address if there is none. -::: - -::: api__content__example -Returns: - -``` -(str) Unused wallet address in base58 -``` -::: diff --git a/content/.vuepress/public/fonts/FontAwesome.otf b/content/.vuepress/public/fonts/FontAwesome.otf deleted file mode 100644 index 8b0f54e47e1d356dcf1496942a50e228e0f1ee14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62856 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