diff --git a/.envrc b/.envrc deleted file mode 100644 index 987d5ea..0000000 --- a/.envrc +++ /dev/null @@ -1 +0,0 @@ -export TODO_FILE=$PWD/TODO diff --git a/.gitignore b/.gitignore index 1fa18c4..80abc54 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,2 @@ -TODO.bak -*.mp4 -channels/index.html -node_modules .DS_Store +tags diff --git a/Makefile b/Makefile index d81310b..7614d7b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,17 @@ -dist: fake - rsync -avzP --exclude .git/ ./ charon:/www/damus.io/ + +all: fake + @echo "you don't need to build anything." + +tags: fake + find js -name '*.js' | grep -v noble-secp256k1 | xargs ctags > "$@" + +emojiregex: fake + @curl -sL 'https://raw.githubusercontent.com/mathiasbynens/emoji-test-regex-pattern/main/dist/latest/javascript.txt' + +dist: + rsync -avzP --delete ./ charon:/www/damus.io/web/ + +dist-staging: + rsync -avzP ./ charon:/www/damus.io/web-staging/ .PHONY: fake diff --git a/README.md b/README.md index e39c86c..f425002 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,62 @@ +# Damus Web -# damus.io +Here lies the code for the Damus web app, a client for the Nostr protocol. The +goal of this client is to be a better version of Twitter, but not to reproduce +all of it's functionality. -The damus.io website +[Issue Tracker](https://todo.sr.ht/~tomtom/damus-web-issues) -## Damus Web +## Roadmap -You can find the damus web app in the `web` directory +Here is what is confirmed for development. -## Contributing + - [ ] Share event + - [ ] Profile view (with ability to follow user) + - [ ] Edit metadata (from profile view) + - [ ] Global timeline view + - [ ] Notifications view + - [ ] Settings view (with ability to configure relays) + - [ ] Multiple reaction picker + - [ ] Direct Messages (subject to discussion) -You can send me patches over nostr or [email][email] at jb55@jb55.com +## Contribution Guide -You can also just hit me up with a git-request-pull and ask me to pull one of -your branches. eg, from github: +There are rules to contributing to this client. Please ensure you read them +before making changes and supplying patch notes. - git request-pull origin/master https://github.com/bob/my-damus-io-fork + - No transpilers. All source code should work out of the box. + - Keep source code organised. Refer to the folder structure. If you have a + question, ask it. + - Do not include your personal tools in the source code. Use your own scripts + outside of the project. This does not include build tools such as Make. + - Use tabs & write JS with snake_case. End of discussion. + - Do not include binary files. + - No NPM (and kin) environments. If you need a file from an external resource + mark the location in the "sources" file and add it to the repo. + - No frameworks. Learn the browser tools and write good code. + - No experimental browser APIs. + - Do not write animations in JavaScript, CSS only. Keep them short and snappy. + Animations should not be a forefront, but an enjoyable addition. + - All new & modified code should be properly documented. + - Source code should be readable in the browser. -If you email or nostr me the output of this command I will be able to review & -merge your changes! +These rules are subject to discussion. + +## Style Guide + +TODO Write about the style guide. + +## Terminology + + * Sign Out - Not "log out", "logout", "log off", etc. + * Sign In - Not "login", "log in", "signin", "sign-in", etc. + * Share - Not "boosted", "retweeted", "repost", etc. + * Send - Not "tweet", "toot", "post", etc. + * Link - Not "share". + +## Known Issues + + * You cannot send events when running from an IP address that is not secure. + Work arounds are not known at this time. -[email]: https://git-send-email.io/ diff --git a/TODO b/TODO deleted file mode 100644 index bac2b86..0000000 --- a/TODO +++ /dev/null @@ -1 +0,0 @@ -video player needs to be outside the timeline, since re-rendering destroys it diff --git a/android/index.html b/android/index.html deleted file mode 100644 index ea4f69b..0000000 --- a/android/index.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - damus - - - - - - - - - - - - - - -
- - damus -
-
-
-

Damus Android crowdfund

-
If ya'll help crowdfund me an android phone I can start working on an android version
- - - - - -
- -

Donations

- -

This is a bolt12 offer, you can pay this with a CLN node. Otherwise press the button to get a bolt11 invoice.

- -
-
- - - -
- Loading donations... -
- - - - - - - diff --git a/channels/Makefile b/channels/Makefile deleted file mode 100644 index b7a5408..0000000 --- a/channels/Makefile +++ /dev/null @@ -1,5 +0,0 @@ - -index.html: channels.ejs ../stats/channels-last-week.json - npx ejs $< -f ../stats/channels-last-week.json -o $@ - - diff --git a/channels/channels.css b/channels/channels.css deleted file mode 100644 index cd6aabd..0000000 --- a/channels/channels.css +++ /dev/null @@ -1,69 +0,0 @@ - - -@import url('https://rsms.me/inter/inter.css'); - -.header { - display: flex; - margin: 50px 0 0 0; - flex-direction: column; - align-items: center; -} - -.logo { - margin-bottom: 0; - letter-spacing: -0.05em; -} - -.date { - font-size: 0.7em; - margin-left: 10px; - color: #eee; -} - -.logo img { - padding-right: 18px; - width: 60px; -} - -a { - font-family: -system-ui, sans-serif; - color: white; -} - -a:visited { - color: #eee; -} - -body { - color: white; - min-height: 800px; -} - -html { - line-height: 1.5; - font-size: 20px; - font-family: sans-serif; - - background: linear-gradient(45deg, rgba(28,85,255,1) 0%, rgba(127,53,171,1) 59%, rgba(255,11,214,1) 100%); -} - -.channel { - display: inline-flex; - align-items: center; -} - -.channel img { - width: 64px; - height: 64px; - border-radius: 50%; - margin-right: 10px; -} - -.container { - margin: 0 auto 0 auto; - max-width: 50em; - hyphens: auto; - word-wrap: break-word; - text-rendering: optimizeLegibility; - font-kerning: normal; -} diff --git a/channels/channels.ejs b/channels/channels.ejs deleted file mode 100644 index feaa775..0000000 --- a/channels/channels.ejs +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - Active nostr channels past week - - - - -
- -
-
- -

Active nostr channels past week

- - - - - - - - - - - <% channels.forEach((channel) => { %> - - - - - - <% }) %> - -
ChannelMessagesID
-
- - <%= channel[1].slice(0,20) %> -
-
<%= channel[0] %>
<%= channel[3] %>
- -

Raw Data

- json
- csv - - -
- - diff --git a/channels/package-lock.json b/channels/package-lock.json deleted file mode 100644 index 711e766..0000000 --- a/channels/package-lock.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "name": "stats", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "requires": { - "balanced-match": "^1.0.0" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "ejs": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.8.tgz", - "integrity": "sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==", - "requires": { - "jake": "^10.8.5" - } - }, - "filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "requires": { - "minimatch": "^5.0.1" - }, - "dependencies": { - "minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==", - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - } - } - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } - } -} diff --git a/channels/package.json b/channels/package.json deleted file mode 100644 index eafcbc6..0000000 --- a/channels/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "stats", - "version": "1.0.0", - "description": "damus stats", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "jb55", - "license": "ISC", - "dependencies": { - "ejs": "^3.1.8" - } -} diff --git a/css/custom.css b/css/custom.css deleted file mode 100644 index e3dd6e1..0000000 --- a/css/custom.css +++ /dev/null @@ -1,191 +0,0 @@ -@import url('https://rsms.me/inter/inter.css'); -html { font-family: 'Inter', sans-serif; } -@supports (font-variation-settings: normal) { - html { font-family: 'Inter var', sans-serif; } -} - -.container { - max-width: 800px; -} - -.blog-container { - font-family: serif; -} - -a { - text-decoration: underline; - font-family: -system-ui, sans-serif; - color: white; -} - -a:visited { - color: #eee; -} - -label { - white-space: nowrap; -} - -blockquote { - font-style: italic; -} - -blockquote:before { - color: #ccc; - content: open-quote; - display: block; - position: relative; - left: -0.6em; - top: 0.3em; - font-size: 4em; - line-height: 0.1em; - vertical-align: -0.4em; -} - -blockquote:after { - color: #ccc; - content: close-quote; - font-size: 4em; - position:relative; - top: 0.2em; - left: -0.1em; - line-height: 0.1em; - vertical-align: -0.4em; -} - -.author { - font-weight: bold; -} - -label input { - margin-left: 10px; - margin-right: 10px; -} - -ul.socials { - margin: 0; - padding: 0; - list-style-type: none; - overflow: hidden; -} - -.profile { - display: flex; - align-content: center; - align-items: center; -} - -.socials-container { - display: flex; - margin: auto; - justify-content: space-evenly; - width: 110px; -} - -ul.socials > li { - float: left; - display: block; - text-align: center; -} - -.socials-container img { - color: #ff0000; - width: 20px; -} - -.row { - margin-bottom: 8rem; -} - -.hero { - margin-top: 5rem; - text-align: center; - clear: left; -} - -.header { - display: flex; - margin-left: 50px; - align-items: center; -} - -.portrait { - border-radius: 50%; - width: 100%; - text-align: center; - box-shadow: 0px 0px 10px #aaa; - border: 2px solid white; -} - -.centered { - text-align: center; -} - -.value-img { - margin: 2.5rem auto 2.5rem auto; - width: 100px; - display: block; - text-align: center; -} - -.credits { - margin-top: 10rem; - text-align: center; - color: #252D3A; -} - -.code-example { - width: 80%; -} - -.value-prop { - margin-top: 3rem; -} - -.value-props { - margin-bottom: 7rem; -} - -.damus { - font-size: 4rem; - letter-spacing: -0.08em; - font-weight: 100; - margin-bottom: 20px; -} - -.title { - font-size: 8rem; - font-weight: 500; - letter-spacing: -0.055em; -} - - -.logo { - margin-bottom: 0; - letter-spacing: -0.05em; -} - -.logo img { - padding-right: 18px; - width: 60px; -} - -.wizards { - font-size: 1.5rem; - top: -2em; - left: 0.2em; - position: relative; - color: #999; -} - -body { - letter-spacing: -0.044em; - margin: 3rem 0 10em 0; - color: white; - background: linear-gradient(45deg, rgba(28,85,255,1) 0%, rgba(127,53,171,1) 59%, rgba(255,11,214,1) 100%); -} - -input { - color: #252D3A; -} - diff --git a/css/normalize.css b/css/normalize.css deleted file mode 100644 index 0edd7c7..0000000 --- a/css/normalize.css +++ /dev/null @@ -1,429 +0,0 @@ -/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ - -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ - -body { - margin: 0; -} - -/* HTML5 display definitions - ========================================================================== */ - -/** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -/** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. - */ - -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. - */ - -[hidden], -template { - display: none; -} - -/* Links - ========================================================================== */ - -/** - * Remove the gray background color from active links in IE 10. - */ - -a { - background-color: transparent; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* Text-level semantics - ========================================================================== */ - -/** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari and Chrome. - */ - -dfn { - font-style: italic; -} - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. - */ - -@media only screen and (max-width: 988px) -{ - h1 { - font-size: calc(100vw / 12.2); - } -} - - -/** - * Address styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* Embedded content - ========================================================================== */ - -/** - * Remove border when inside `a` element in IE 8/9/10. - */ - -img { - border: 0; -} - -/** - * Correct overflow not hidden in IE 9/10/11. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* Grouping content - ========================================================================== */ - -/** - * Address margin not present in IE 8/9 and Safari. - */ - -figure { - margin: 1em 40px; -} - -/** - * Address differences between Firefox and other browsers. - */ - -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} - -/** - * Contain overflow in all browsers. - */ - -pre { - overflow: auto; -} - -/** - * Address odd `em`-unit font size rendering in all browsers. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -/* Forms - ========================================================================== */ - -/** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. - */ - -/** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. - */ - -button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address `overflow` set to `hidden` in IE 8/9/10/11. - */ - -button { - overflow: visible; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. - */ - -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ - -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -input { - line-height: normal; -} - -/** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. - */ - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Remove default vertical scrollbar in IE 8/9/10/11. - */ - -textarea { - overflow: auto; -} - -/** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. - */ - -optgroup { - font-weight: bold; -} - -/* Tables - ========================================================================== */ - -/** - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} diff --git a/web/css/responsive.css b/css/responsive.css similarity index 100% rename from web/css/responsive.css rename to css/responsive.css diff --git a/css/skeleton.css b/css/skeleton.css deleted file mode 100644 index 2152460..0000000 --- a/css/skeleton.css +++ /dev/null @@ -1,421 +0,0 @@ -/* -* Skeleton V2.0.4 -* Copyright 2014, Dave Gamache -* www.getskeleton.com -* Free to use under the MIT license. -* http://www.opensource.org/licenses/mit-license.php -* 12/29/2014 -*/ - - -/* Table of contents -–––––––––––––––––––––––––––––––––––––––––––––––––– -- Grid -- Base Styles -- Typography -- Links -- Buttons -- Forms -- Lists -- Code -- Tables -- Spacing -- Utilities -- Clearing -- Media Queries -*/ - - -/* Grid -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -.container { - position: relative; - width: 100%; - max-width: 960px; - margin: 0 auto; - padding: 0 20px; - box-sizing: border-box; } -.column, -.columns { - width: 100%; - float: left; - box-sizing: border-box; } - -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 85%; - padding: 0; } -} - -/* For devices larger than 550px */ -@media (min-width: 550px) { - .container { - width: 80%; } - .column, - .columns { - margin-left: 4%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } - - .one.column, - .one.columns { width: 4.66666666667%; } - .two.columns { width: 13.3333333333%; } - .three.columns { width: 22%; } - .four.columns { width: 30.6666666667%; } - .five.columns { width: 39.3333333333%; } - .six.columns { width: 48%; } - .seven.columns { width: 56.6666666667%; } - .eight.columns { width: 65.3333333333%; } - .nine.columns { width: 74.0%; } - .ten.columns { width: 82.6666666667%; } - .eleven.columns { width: 91.3333333333%; } - .twelve.columns { width: 100%; margin-left: 0; } - - .one-third.column { width: 30.6666666667%; } - .two-thirds.column { width: 65.3333333333%; } - - .one-half.column { width: 48%; } - - /* Offsets */ - .offset-by-one.column, - .offset-by-one.columns { margin-left: 8.66666666667%; } - .offset-by-two.column, - .offset-by-two.columns { margin-left: 17.3333333333%; } - .offset-by-three.column, - .offset-by-three.columns { margin-left: 26%; } - .offset-by-four.column, - .offset-by-four.columns { margin-left: 34.6666666667%; } - .offset-by-five.column, - .offset-by-five.columns { margin-left: 43.3333333333%; } - .offset-by-six.column, - .offset-by-six.columns { margin-left: 52%; } - .offset-by-seven.column, - .offset-by-seven.columns { margin-left: 60.6666666667%; } - .offset-by-eight.column, - .offset-by-eight.columns { margin-left: 69.3333333333%; } - .offset-by-nine.column, - .offset-by-nine.columns { margin-left: 78.0%; } - .offset-by-ten.column, - .offset-by-ten.columns { margin-left: 86.6666666667%; } - .offset-by-eleven.column, - .offset-by-eleven.columns { margin-left: 95.3333333333%; } - - .offset-by-one-third.column, - .offset-by-one-third.columns { margin-left: 34.6666666667%; } - .offset-by-two-thirds.column, - .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } - - .offset-by-one-half.column, - .offset-by-one-half.columns { margin-left: 52%; } - -} - - -/* Base Styles -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -/* NOTE -html is set to 62.5% so that all the REM measurements throughout Skeleton -are based on 10px sizing. So basically 1.5rem = 15px :) */ -html { - font-size: 62.5%; } -body { - min-height: 800px; - font-size: 1.6em; /* currently ems cause chrome bug misinterpreting rems on body element */ - line-height: 1.6; - font-weight: 400; - color: #222; } - - -/* Typography -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: 2rem; - font-weight: 300; } -h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} -h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } -h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } -h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } -h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.08rem; } -h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } - -/* Larger than phablet */ -@media (min-width: 550px) { - h1 { font-size: 5.0rem; } - h2 { font-size: 4.2rem; } - h3 { font-size: 3.6rem; } - h4 { font-size: 3.0rem; } - h5 { font-size: 2.4rem; } - h6 { font-size: 1.5rem; } -} - -p { - margin-top: 0; } - - -/* Links -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -a { - color: #0595ad; - text-decoration: none; -} -a:hover { - color: #9BBDF2; -} - - -/* Buttons -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -.button, -button, -input[type="submit"], -input[type="reset"], -input[type="button"] { - display: inline-block; - height: 38px; - padding: 0 30px; - color: white; - text-align: center; - font-size: 11px; - font-weight: 600; - line-height: 38px; - letter-spacing: .1rem; - text-transform: uppercase; - text-decoration: none; - white-space: nowrap; - background-color: transparent; - border-radius: 4px; - border: 1px solid #bbb; - cursor: pointer; - box-sizing: border-box; } -.button:hover, -button:hover, -input[type="submit"]:hover, -input[type="reset"]:hover, -input[type="button"]:hover, -.button:focus, -button:focus, -input[type="submit"]:focus, -input[type="reset"]:focus, -input[type="button"]:focus { - color: #999; - border-color: #999; - outline: 0; } -.button.button-primary, -button.button-primary, -input[type="submit"].button-primary, -input[type="reset"].button-primary, -input[type="button"].button-primary { - color: #FFF; - background-color: #33C3F0; - border-color: #33C3F0; } -.button.button-primary:hover, -button.button-primary:hover, -input[type="submit"].button-primary:hover, -input[type="reset"].button-primary:hover, -input[type="button"].button-primary:hover, -.button.button-primary:focus, -button.button-primary:focus, -input[type="submit"].button-primary:focus, -input[type="reset"].button-primary:focus, -input[type="button"].button-primary:focus { - color: #FFF; - background-color: #1EAEDB; - border-color: #1EAEDB; } - - -/* Forms -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -input[type="email"], -input[type="number"], -input[type="search"], -input[type="text"], -input[type="tel"], -input[type="url"], -input[type="password"], -textarea, -select { - height: 38px; - padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ - background-color: #fff; - border: 1px solid #D1D1D1; - border-radius: 4px; - box-shadow: none; - box-sizing: border-box; } -/* Removes awkward default styles on some inputs for iOS */ -input[type="email"], -input[type="number"], -input[type="search"], -input[type="text"], -input[type="tel"], -input[type="url"], -input[type="password"], -textarea { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; } -textarea { - min-height: 65px; - padding-top: 6px; - padding-bottom: 6px; } -input[type="email"]:focus, -input[type="number"]:focus, -input[type="search"]:focus, -input[type="text"]:focus, -input[type="tel"]:focus, -input[type="url"]:focus, -input[type="password"]:focus, -textarea:focus, -select:focus { - border: 1px solid #33C3F0; - outline: 0; } -label, -legend { - /* display: block; */ - margin-bottom: .5rem; - /* font-weight: 600; */ } -fieldset { - padding: 0; - border-width: 0; } -input[type="checkbox"], -input[type="radio"] { - display: inline; } -label > .label-body { - display: inline-block; - margin-left: .5rem; - font-weight: normal; } - - -/* Lists -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -ul { - list-style: circle inside; } -ol { - list-style: decimal inside; } -ol, ul { - padding-left: 0; - margin-top: 0; } -ul ul, -ul ol, -ol ol, -ol ul { - margin: 1.5rem 0 1.5rem 3rem; - font-size: 90%; } -li { - margin-bottom: 0.2rem; } - - -/* Code -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -code { - padding: .2rem .5rem; - margin: 0 .2rem; - font-size: 90%; - white-space: nowrap; - background: #F1F1F1; - border: 1px solid #E1E1E1; - border-radius: 4px; } -pre > code { - display: block; - padding: 1rem 1.5rem; - white-space: pre; } - - -/* Tables -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -th, -td { - padding: 12px 15px; - text-align: left; - border-bottom: 1px solid #E1E1E1; } -th:first-child, -td:first-child { - padding-left: 0; } -th:last-child, -td:last-child { - padding-right: 0; } - - -/* Spacing -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -button, -.button { - margin-bottom: 1rem; } -input, -textarea, -select, -fieldset { - margin-bottom: 1.5rem; } -pre, -blockquote, -dl, -figure, -table, -p, -ul, -ol, -form { - margin-bottom: 2.5rem; } - - -/* Utilities -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -.u-full-width { - width: 100%; - box-sizing: border-box; } -.u-max-full-width { - max-width: 100%; - box-sizing: border-box; } -.u-pull-right { - float: right; } -.u-pull-left { - float: left; } - - -/* Misc -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -hr { - margin-top: 3rem; - margin-bottom: 3.5rem; - border-width: 0; - border-top: 1px solid #E1E1E1; } - - -/* Clearing -–––––––––––––––––––––––––––––––––––––––––––––––––– */ - -/* Self Clearing Goodness */ -.container:after, -.row:after, -.u-cf { - content: ""; - display: table; - clear: both; } - - -/* Media Queries -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -/* -Note: The best way to structure the use of media queries is to create the queries -near the relevant code. For example, if you wanted to change the styles for buttons -on small devices, paste the mobile query code up in the buttons section and style it -there. -*/ - - -/* Larger than mobile */ -@media (min-width: 400px) {} - -/* Larger than phablet (also point when grid becomes active) */ -@media (min-width: 550px) {} - -/* Larger than tablet */ -@media (min-width: 750px) {} - -/* Larger than desktop */ -@media (min-width: 1000px) {} - -/* Larger than Desktop HD */ -@media (min-width: 1200px) {} diff --git a/web/css/styles.css b/css/styles.css similarity index 100% rename from web/css/styles.css rename to css/styles.css diff --git a/web/css/utils.css b/css/utils.css similarity index 100% rename from web/css/utils.css rename to css/utils.css diff --git a/web/css/vars.css b/css/vars.css similarity index 100% rename from web/css/vars.css rename to css/vars.css diff --git a/favicon.ico b/favicon.ico deleted file mode 100644 index 13c1506..0000000 Binary files a/favicon.ico and /dev/null differ diff --git a/web/icon/close-modal.svg b/icon/close-modal.svg similarity index 100% rename from web/icon/close-modal.svg rename to icon/close-modal.svg diff --git a/web/icon/content-warning.svg b/icon/content-warning.svg similarity index 100% rename from web/icon/content-warning.svg rename to icon/content-warning.svg diff --git a/web/icon/event-delete.svg b/icon/event-delete.svg similarity index 100% rename from web/icon/event-delete.svg rename to icon/event-delete.svg diff --git a/web/icon/event-like.svg b/icon/event-like.svg similarity index 100% rename from web/icon/event-like.svg rename to icon/event-like.svg diff --git a/web/icon/event-liked.svg b/icon/event-liked.svg similarity index 100% rename from web/icon/event-liked.svg rename to icon/event-liked.svg diff --git a/web/icon/event-reply.svg b/icon/event-reply.svg similarity index 100% rename from web/icon/event-reply.svg rename to icon/event-reply.svg diff --git a/web/icon/explore-active.svg b/icon/explore-active.svg similarity index 100% rename from web/icon/explore-active.svg rename to icon/explore-active.svg diff --git a/web/icon/explore.svg b/icon/explore.svg similarity index 100% rename from web/icon/explore.svg rename to icon/explore.svg diff --git a/web/icon/home-active.svg b/icon/home-active.svg similarity index 100% rename from web/icon/home-active.svg rename to icon/home-active.svg diff --git a/web/icon/home.svg b/icon/home.svg similarity index 100% rename from web/icon/home.svg rename to icon/home.svg diff --git a/web/icon/key.svg b/icon/key.svg similarity index 100% rename from web/icon/key.svg rename to icon/key.svg diff --git a/web/icon/loader-fragment.svg b/icon/loader-fragment.svg similarity index 100% rename from web/icon/loader-fragment.svg rename to icon/loader-fragment.svg diff --git a/web/icon/logo-inverted.svg b/icon/logo-inverted.svg similarity index 100% rename from web/icon/logo-inverted.svg rename to icon/logo-inverted.svg diff --git a/web/icon/logo.svg b/icon/logo.svg similarity index 100% rename from web/icon/logo.svg rename to icon/logo.svg diff --git a/web/icon/message-user.svg b/icon/message-user.svg similarity index 100% rename from web/icon/message-user.svg rename to icon/message-user.svg diff --git a/web/icon/no-user.svg b/icon/no-user.svg similarity index 100% rename from web/icon/no-user.svg rename to icon/no-user.svg diff --git a/web/icon/notifications-active.svg b/icon/notifications-active.svg similarity index 100% rename from web/icon/notifications-active.svg rename to icon/notifications-active.svg diff --git a/web/icon/notifications.svg b/icon/notifications.svg similarity index 100% rename from web/icon/notifications.svg rename to icon/notifications.svg diff --git a/web/icon/open-thread.svg b/icon/open-thread.svg similarity index 100% rename from web/icon/open-thread.svg rename to icon/open-thread.svg diff --git a/web/icon/pubkey.svg b/icon/pubkey.svg similarity index 100% rename from web/icon/pubkey.svg rename to icon/pubkey.svg diff --git a/web/icon/read-more.svg b/icon/read-more.svg similarity index 100% rename from web/icon/read-more.svg rename to icon/read-more.svg diff --git a/web/icon/sign-out.svg b/icon/sign-out.svg similarity index 100% rename from web/icon/sign-out.svg rename to icon/sign-out.svg diff --git a/img/activation.svg b/img/activation.svg deleted file mode 100644 index 3338066..0000000 --- a/img/activation.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/app-store-coming-soon.svg b/img/app-store-coming-soon.svg deleted file mode 100644 index 0ae7f5c..0000000 --- a/img/app-store-coming-soon.svg +++ /dev/null @@ -1,148 +0,0 @@ - - - - -Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Download_on_the_App_Store_Badge_US-UK_RGB_blk_4SVG_092917Coming soon to diff --git a/img/appstore.svg b/img/appstore.svg deleted file mode 100644 index 6d65444..0000000 --- a/img/appstore.svg +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/img/bitcoin-p2p.png b/img/bitcoin-p2p.png deleted file mode 100644 index b989e78..0000000 Binary files a/img/bitcoin-p2p.png and /dev/null differ diff --git a/img/bitcoin-p2p.svg b/img/bitcoin-p2p.svg deleted file mode 100644 index 1a6184b..0000000 --- a/img/bitcoin-p2p.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/bitcoin-phone.svg b/img/bitcoin-phone.svg deleted file mode 100644 index 50b0e8c..0000000 --- a/img/bitcoin-phone.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/bot.svg b/img/bot.svg deleted file mode 100644 index 25d41d6..0000000 --- a/img/bot.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/communication.svg b/img/communication.svg deleted file mode 100644 index 869b786..0000000 --- a/img/communication.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/damus-nobg.svg b/img/damus-nobg.svg deleted file mode 100644 index 5f14838..0000000 --- a/img/damus-nobg.svg +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/img/damus.svg b/img/damus.svg deleted file mode 100644 index 44b3849..0000000 --- a/img/damus.svg +++ /dev/null @@ -1,184 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/img/damus_notif.svg b/img/damus_notif.svg deleted file mode 100644 index d1f29be..0000000 --- a/img/damus_notif.svg +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/img/digital-nomad.png b/img/digital-nomad.png deleted file mode 100644 index e2e2f21..0000000 Binary files a/img/digital-nomad.png and /dev/null differ diff --git a/img/digital-nomad.svg b/img/digital-nomad.svg deleted file mode 100644 index ea6abba..0000000 --- a/img/digital-nomad.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/encrypted-message.png b/img/encrypted-message.png deleted file mode 100644 index 756d585..0000000 Binary files a/img/encrypted-message.png and /dev/null differ diff --git a/img/freelance.svg b/img/freelance.svg deleted file mode 100644 index 6836862..0000000 --- a/img/freelance.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/logo.png b/img/logo.png deleted file mode 100644 index 404f7ca..0000000 Binary files a/img/logo.png and /dev/null differ diff --git a/img/message.svg b/img/message.svg deleted file mode 100644 index 3566de2..0000000 --- a/img/message.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/protection.svg b/img/protection.svg deleted file mode 100644 index e9d22f6..0000000 --- a/img/protection.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/social-media.svg b/img/social-media.svg deleted file mode 100644 index 0164095..0000000 --- a/img/social-media.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/ss.png b/img/ss.png deleted file mode 100644 index 8ea7d47..0000000 Binary files a/img/ss.png and /dev/null differ diff --git a/img/testflight.svg b/img/testflight.svg deleted file mode 100644 index be9feb0..0000000 --- a/img/testflight.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - testflight - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/img/undercover.png b/img/undercover.png deleted file mode 100644 index eafa17c..0000000 Binary files a/img/undercover.png and /dev/null differ diff --git a/img/undercover.svg b/img/undercover.svg deleted file mode 100644 index 97b5216..0000000 --- a/img/undercover.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/index.html b/index.html index d3eaf04..2f31054 100644 --- a/index.html +++ b/index.html @@ -1,83 +1,272 @@ - - - - damus - + + + + - - - - - - - - - - - - - -
- - damus -
-
-
-

The social network you control -

Your very own Twitter for your friends or business.
- - - -
-
- - You are in control. Built on open internet protocols, there is no platform that can ban or censor you. You are in control of your data & speech. -
-
- - Encrypted. End-to-End encrypted private messaging. Keep big tech out of your DMs. -
-
- - No registration required. Creating an account doesn't require a phone number, email or name. Get started right away with zero friction. -
-
-
-
- - No servers required. Messages are distributed via decentralized relays. No need to run any infrastructure and there are no single points of failure. Simple! -
-
- - Programmable. Easily integrate bots that automate your life or business. Get notified when your servers go down, retweet to your team and collaborate in realtime. -
-
- - Earn money. Tip your friend's posts and stack sats with Bitcoin & ⚡️, the native currency of the internet.
-
- - - - -
- + Damus + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
-
+
+
+
+

+ Yo, Sup? + +

+

The blue bird experience for Nostr.

+ +
+
+ +
+
+
+ +
+ + +
+
+ +
+
+
+ +
+
+
+ +
+
+ +
+ + + +
+
+
+
+
+ +
+ + + +
+
+
+ +

+
+
+
+
+ +
+
+
+ +
+
+
+
+
+
+
+ + + + + + -
- - - - - + diff --git a/web/js/bech32.js b/js/bech32.js similarity index 100% rename from web/js/bech32.js rename to js/bech32.js diff --git a/web/js/contacts.js b/js/contacts.js similarity index 100% rename from web/js/contacts.js rename to js/contacts.js diff --git a/web/js/core.js b/js/core.js similarity index 100% rename from web/js/core.js rename to js/core.js diff --git a/web/js/event.js b/js/event.js similarity index 100% rename from web/js/event.js rename to js/event.js diff --git a/web/js/lib.js b/js/lib.js similarity index 100% rename from web/js/lib.js rename to js/lib.js diff --git a/js/lnsocket.js b/js/lnsocket.js deleted file mode 100644 index 6c7d158..0000000 --- a/js/lnsocket.js +++ /dev/null @@ -1,391 +0,0 @@ - -var Module = (() => { - var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined; - - return ( -function(Module) { - Module = Module || {}; - -var Module=typeof Module!="undefined"?Module:{};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});Module.getRandomValue=function(){const window_="object"===typeof window?window:this;const crypto_=typeof window_.crypto!=="undefined"?window_.crypto:window_.msCrypto;let randomBytesNode;if(!crypto_){randomBytesNode=require("crypto").randomBytes;fn=randomValuesNode}else{fn=randomValuesStandard}function randomValuesNode(){return randomBytesNode(1)[0]>>>0}function randomValuesStandard(){var buf=new Uint32Array(1);crypto_.getRandomValues(buf);return buf[0]>>>0}return fn}();var moduleOverrides=Object.assign({},Module);var arguments_=[];var thisProgram="./this.program";var quit_=(status,toThrow)=>{throw toThrow};var ENVIRONMENT_IS_WEB=true;var ENVIRONMENT_IS_WORKER=false;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.replace(/[?#].*/,"").lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=(url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText});if(ENVIRONMENT_IS_WORKER){readBinary=(url=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)})}readAsync=((url,onload,onerror)=>{var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=(()=>{if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()});xhr.onerror=onerror;xhr.send(null)})}setWindowTitle=(title=>document.title=title)}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);Object.assign(Module,moduleOverrides);moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;function getCFunc(ident){var func=Module["_"+ident];return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i=endIdx))++endPtr;if(endPtr-idx>16&&heap.subarray&&UTF8Decoder){return UTF8Decoder.decode(heap.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,heap,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;heap[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;heap[outIdx++]=192|u>>6;heap[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;heap[outIdx++]=224|u>>12;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;heap[outIdx++]=240|u>>18;heap[outIdx++]=128|u>>12&63;heap[outIdx++]=128|u>>6&63;heap[outIdx++]=128|u&63}}heap[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var INITIAL_MEMORY=Module["INITIAL_MEMORY"]||16777216;var wasmTable;var __ATPRERUN__=[];var __ATINIT__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;callRuntimeCallbacks(__ATINIT__)}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnInit(cb){__ATINIT__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){{if(Module["onAbort"]){Module["onAbort"](what)}}what="Aborted("+what+")";err(what);ABORT=true;EXITSTATUS=1;what+=". Build with -s ASSERTIONS=1 for more info.";var e=new WebAssembly.RuntimeError(what);readyPromiseReject(e);throw e}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return filename.startsWith(dataURIPrefix)}var wasmBinaryFile;wasmBinaryFile="lnsocket.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(file){try{if(file==wasmBinaryFile&&wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(file)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)){if(typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary(wasmBinaryFile)})}}return Promise.resolve().then(function(){return getBinary(wasmBinaryFile)})}function createWasm(){var info={"a":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;wasmMemory=Module["asm"]["i"];updateGlobalBufferAndViews(wasmMemory.buffer);wasmTable=Module["asm"]["m"];addOnInit(Module["asm"]["j"]);removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiationResult(result){receiveInstance(result["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(function(instance){return instance}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming=="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch=="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiationResult,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");return instantiateArrayBuffer(receiveInstantiationResult)})})}else{return instantiateArrayBuffer(receiveInstantiationResult)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync().catch(readyPromiseReject);return{}}var ASM_CONSTS={70252:function(){return Module.getRandomValue()},70288:function(){if(Module.getRandomValue===undefined){try{var window_="object"===typeof window?window:self;var crypto_=typeof window_.crypto!=="undefined"?window_.crypto:window_.msCrypto;var randomValuesStandard=function(){var buf=new Uint32Array(1);crypto_.getRandomValues(buf);return buf[0]>>>0};randomValuesStandard();Module.getRandomValue=randomValuesStandard}catch(e){try{var crypto=require("crypto");var randomValueNodeJS=function(){var buf=crypto["randomBytes"](4);return(buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3])>>>0};randomValueNodeJS();Module.getRandomValue=randomValueNodeJS}catch(e){throw"No secure random number generator found"}}}}};function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback(Module);continue}var func=callback.func;if(typeof func=="number"){if(callback.arg===undefined){getWasmTableEntry(func)()}else{getWasmTableEntry(func)(callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}function getWasmTableEntry(funcPtr){return wasmTable.get(funcPtr)}function ___assert_fail(condition,filename,line,func){abort("Assertion failed: "+UTF8ToString(condition)+", at: "+[filename?UTF8ToString(filename):"unknown filename",line,func?UTF8ToString(func):"unknown function"])}function _abort(){abort("")}var readAsmConstArgsArray=[];function readAsmConstArgs(sigPtr,buf){readAsmConstArgsArray.length=0;var ch;buf>>=2;while(ch=HEAPU8[sigPtr++]){var readAsmConstArgsDouble=ch<105;if(readAsmConstArgsDouble&&buf&1)buf++;readAsmConstArgsArray.push(readAsmConstArgsDouble?HEAPF64[buf++>>1]:HEAP32[buf]);++buf}return readAsmConstArgsArray}function _emscripten_asm_const_int(code,sigPtr,argbuf){var args=readAsmConstArgs(sigPtr,argbuf);return ASM_CONSTS[code].apply(null,args)}function _emscripten_memcpy_big(dest,src,num){HEAPU8.copyWithin(dest,src,src+num)}function abortOnCannotGrowMemory(requestedSize){abort("OOM")}function _emscripten_resize_heap(requestedSize){var oldSize=HEAPU8.length;requestedSize=requestedSize>>>0;abortOnCannotGrowMemory(requestedSize)}var SYSCALLS={buffers:[null,[],[]],printChar:function(stream,curr){var buffer=SYSCALLS.buffers[stream];if(curr===0||curr===10){(stream===1?out:err)(UTF8ArrayToString(buffer,0));buffer.length=0}else{buffer.push(curr)}},varargs:undefined,get:function(){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(ptr){var ret=UTF8ToString(ptr);return ret},get64:function(low,high){return low}};function _fd_close(fd){return 0}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){}function _fd_write(fd,iov,iovcnt,pnum){var num=0;for(var i=0;i>2];var len=HEAP32[iov+4>>2];iov+=8;for(var j=0;j>2]=num;return 0}var asmLibraryArg={"a":___assert_fail,"b":_abort,"h":_emscripten_asm_const_int,"g":_emscripten_memcpy_big,"c":_emscripten_resize_heap,"f":_fd_close,"d":_fd_seek,"e":_fd_write};var asm=createWasm();var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return(___wasm_call_ctors=Module["___wasm_call_ctors"]=Module["asm"]["j"]).apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return(_malloc=Module["_malloc"]=Module["asm"]["k"]).apply(null,arguments)};var _free=Module["_free"]=function(){return(_free=Module["_free"]=Module["asm"]["l"]).apply(null,arguments)};var _lnsocket_make_default_initmsg=Module["_lnsocket_make_default_initmsg"]=function(){return(_lnsocket_make_default_initmsg=Module["_lnsocket_make_default_initmsg"]=Module["asm"]["n"]).apply(null,arguments)};var _lnsocket_encrypt=Module["_lnsocket_encrypt"]=function(){return(_lnsocket_encrypt=Module["_lnsocket_encrypt"]=Module["asm"]["o"]).apply(null,arguments)};var _lnsocket_decrypt=Module["_lnsocket_decrypt"]=function(){return(_lnsocket_decrypt=Module["_lnsocket_decrypt"]=Module["asm"]["p"]).apply(null,arguments)};var _lnsocket_decrypt_header=Module["_lnsocket_decrypt_header"]=function(){return(_lnsocket_decrypt_header=Module["_lnsocket_decrypt_header"]=Module["asm"]["q"]).apply(null,arguments)};var _lnsocket_make_ping_msg=Module["_lnsocket_make_ping_msg"]=function(){return(_lnsocket_make_ping_msg=Module["_lnsocket_make_ping_msg"]=Module["asm"]["r"]).apply(null,arguments)};var _lnsocket_msgbuf=Module["_lnsocket_msgbuf"]=function(){return(_lnsocket_msgbuf=Module["_lnsocket_msgbuf"]=Module["asm"]["s"]).apply(null,arguments)};var _lnsocket_create=Module["_lnsocket_create"]=function(){return(_lnsocket_create=Module["_lnsocket_create"]=Module["asm"]["t"]).apply(null,arguments)};var _lnsocket_destroy=Module["_lnsocket_destroy"]=function(){return(_lnsocket_destroy=Module["_lnsocket_destroy"]=Module["asm"]["u"]).apply(null,arguments)};var _lnsocket_secp=Module["_lnsocket_secp"]=function(){return(_lnsocket_secp=Module["_lnsocket_secp"]=Module["asm"]["v"]).apply(null,arguments)};var _lnsocket_genkey=Module["_lnsocket_genkey"]=function(){return(_lnsocket_genkey=Module["_lnsocket_genkey"]=Module["asm"]["w"]).apply(null,arguments)};var _lnsocket_print_errors=Module["_lnsocket_print_errors"]=function(){return(_lnsocket_print_errors=Module["_lnsocket_print_errors"]=Module["asm"]["x"]).apply(null,arguments)};var _lnsocket_act_two=Module["_lnsocket_act_two"]=function(){return(_lnsocket_act_two=Module["_lnsocket_act_two"]=Module["asm"]["y"]).apply(null,arguments)};var _commando_make_rpc_msg=Module["_commando_make_rpc_msg"]=function(){return(_commando_make_rpc_msg=Module["_commando_make_rpc_msg"]=Module["asm"]["z"]).apply(null,arguments)};var _lnsocket_act_one=Module["_lnsocket_act_one"]=function(){return(_lnsocket_act_one=Module["_lnsocket_act_one"]=Module["asm"]["A"]).apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return(stackSave=Module["stackSave"]=Module["asm"]["B"]).apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return(stackRestore=Module["stackRestore"]=Module["asm"]["C"]).apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return(stackAlloc=Module["stackAlloc"]=Module["asm"]["D"]).apply(null,arguments)};Module["ccall"]=ccall;Module["cwrap"]=cwrap;var calledRun;dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0){return}function doRun(){if(calledRun)return;calledRun=true;Module["calledRun"]=true;if(ABORT)return;initRuntime();readyPromiseResolve(Module);if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}run(); - - - return Module.ready -} -); -})(); -if (typeof exports === 'object' && typeof module === 'object') - module.exports = Module; -else if (typeof define === 'function' && define['amd']) - define([], function() { return Module; }); -else if (typeof exports === 'object') - exports["Module"] = Module; - -async function lnsocket_init() { - const module = await Module() - - function SocketImpl(host) { - if (!(this instanceof SocketImpl)) - return new SocketImpl(host) - - if (typeof WebSocket !== 'undefined') { - console.log("WebSocket", typeof WebSocket) - const ok = host.startsWith("ws://") || host.startsWith("wss://") - if (!ok) - throw new Error("host must start with ws:// or wss://") - const ws = new WebSocket(host) - ws.ondata = function(fn) { - ws.onmessage = (v) => { - const data = v.data.arrayBuffer() - fn(data) - } - } - return ws - } - - // - // we're in nodejs - // - const net = require('net') - let [hostname,port] = host.split(":") - port = +port || 9735 - const socket = net.createConnection(port, hostname, () => { - socket.emit("open") - }) - socket.addEventListener = socket.on.bind(socket) - - if (socket.onmessage) - throw new Error("socket already has onmessage?") - - socket.ondata = (fn) => { - socket.on('data', fn) - } - - socket.close = () => { - socket.destroy() - } - - if (socket.send) - throw new Error("socket already has send?") - - socket.send = function socket_send(data) { - return new Promise((resolve, reject) => { - socket.write(data, resolve) - }); - } - - return socket - } - - const ACT_ONE_SIZE = 50 - const ACT_TWO_SIZE = 50 - const ACT_THREE_SIZE = 66 - const DEFAULT_TIMEOUT = 15000 - - const COMMANDO_REPLY_CONTINUES = 0x594b - const COMMANDO_REPLY_TERM = 0x594d - - const lnsocket_create = module.cwrap("lnsocket_create", "number") - const lnsocket_destroy = module.cwrap("lnsocket_destroy", "number") - const lnsocket_encrypt = module.cwrap("lnsocket_encrypt", "number", ["int", "array", "int", "int"]) - const lnsocket_decrypt = module.cwrap("lnsocket_decrypt", "number", ["int", "array", "int"]) - const lnsocket_decrypt_header = module.cwrap("lnsocket_decrypt_header", "number", ["number", "array"]) - const lnsocket_msgbuf = module.cwrap("lnsocket_msgbuf", "number", ["int"]) - const lnsocket_act_one = module.cwrap("lnsocket_act_one", "number", ["number", "string"]) - const lnsocket_act_two = module.cwrap("lnsocket_act_two", "number", ["number", "array"]) - const lnsocket_print_errors = module.cwrap("lnsocket_print_errors", "int") - const lnsocket_genkey = module.cwrap("lnsocket_genkey", "int") - const lnsocket_make_default_initmsg = module.cwrap("lnsocket_make_default_initmsg", "int", ["int", "int"]) - const lnsocket_make_ping_msg = module.cwrap("lnsocket_make_ping_msg", "int", ["int", "int", "int", "int"]) - const commando_make_rpc_msg = module.cwrap("commando_make_rpc_msg", "int", ["string", "string", "string", "number", "int", "int"]) - - function concat_u8_arrays(arrays) { - // sum of individual array lengths - let totalLength = arrays.reduce((acc, value) => - acc + (value.length || value.byteLength) - , 0); - - if (!arrays.length) return null; - - let result = new Uint8Array(totalLength); - - let length = 0; - for (let array of arrays) { - if (array instanceof ArrayBuffer) - result.set(new Uint8Array(array), length); - else - result.set(array, length); - - length += (array.length || array.byteLength); - } - - return result; - } - - function parse_msgtype(buf) { - return buf[0] << 8 | buf[1] - } - - function wasm_mem(ptr, size) { - return new Uint8Array(module.HEAPU8.buffer, ptr, size); - } - - function LNSocket(opts) { - if (!(this instanceof LNSocket)) - return new LNSocket(opts) - - this.opts = opts || { - timeout: DEFAULT_TIMEOUT - } - this.queue = [] - this.ln = lnsocket_create() - } - - LNSocket.prototype.queue_recv = function() { - let self = this - return new Promise((resolve, reject) => { - const checker = setInterval(() => { - const val = self.queue.shift() - if (val) { - clearInterval(checker) - resolve(val) - } else if (!self.connected) { - clearInterval(checker) - reject() - } - }, 5); - }) - } - - LNSocket.prototype.print_errors = function _lnsocket_print_errors() { - lnsocket_print_errors(this.ln) - } - - LNSocket.prototype.genkey = function _lnsocket_genkey() { - lnsocket_genkey(this.ln) - } - - LNSocket.prototype.act_one_data = function _lnsocket_act_one(node_id) { - const act_one_ptr = lnsocket_act_one(this.ln, node_id) - if (act_one_ptr === 0) - return null - return wasm_mem(act_one_ptr, ACT_ONE_SIZE) - } - - LNSocket.prototype.act_two = function _lnsocket_act_two(act2) { - const act_three_ptr = lnsocket_act_two(this.ln, new Uint8Array(act2)) - if (act_three_ptr === 0) { - this.print_errors() - return null - } - return wasm_mem(act_three_ptr, ACT_THREE_SIZE) - } - - LNSocket.prototype.connect = async function lnsocket_connect(node_id, host) { - await handle_connect(this, node_id, host) - - const act1 = this.act_one_data(node_id) - this.ws.send(act1) - const act2 = await this.read_all(ACT_TWO_SIZE) - if (act2.length != ACT_TWO_SIZE) { - throw new Error(`expected act2 to be ${ACT_TWO_SIZE} long, got ${act2.length}`) - } - const act3 = this.act_two(act2) - this.ws.send(act3) - } - - LNSocket.prototype.connect_and_init = async function _connect_and_init(node_id, host) { - await this.connect(node_id, host) - await this.perform_init() - } - - LNSocket.prototype.read_all = async function read_all(n) { - let count = 0 - let chunks = [] - if (!this.connected) - throw new Error("read_all: not connected") - while (true) { - let res = await this.queue_recv() - - const remaining = n - count - - if (res.byteLength > remaining) { - chunks.push(res.slice(0, remaining)) - this.queue.unshift(res.slice(remaining)) - break - } else if (res.byteLength === remaining) { - chunks.push(res) - break - } - - chunks.push(res) - count += res.byteLength - } - - return concat_u8_arrays(chunks) - } - - LNSocket.prototype.read_header = async function read_header() { - const header = await this.read_all(18) - if (header.length != 18) - throw new Error("Failed to read header") - return lnsocket_decrypt_header(this.ln, header) - } - - LNSocket.prototype.rpc = async function lnsocket_rpc(opts) { - const msg = this.make_commando_msg(opts) - this.write(msg) - const res = await this.read_all_rpc() - return JSON.parse(res) - } - - LNSocket.prototype.recv = async function lnsocket_recv() { - const msg = await this.read() - const msgtype = parse_msgtype(msg.slice(0,2)) - const res = [msgtype, msg.slice(2)] - return res - } - - LNSocket.prototype.read_all_rpc = async function read_all_rpc() { - let chunks = [] - while (true) { - const [typ, msg] = await this.recv() - switch (typ) { - case COMMANDO_REPLY_TERM: - chunks.push(msg.slice(8)) - return new TextDecoder().decode(concat_u8_arrays(chunks)); - case COMMANDO_REPLY_CONTINUES: - chunks.push(msg.slice(8)) - break - default: - console.log("got unknown type", typ) - continue - } - } - } - - LNSocket.prototype.make_commando_msg = function _lnsocket_make_commando_msg(opts) { - const buflen = 4096 - let len = 0; - const buf = module._malloc(buflen); - module.HEAPU8.set(Uint8Array, buf); - - const params = JSON.stringify(opts.params||{}) - if (!(len = commando_make_rpc_msg(opts.method, params, opts.rune, - 0, buf, buflen))) { - throw new Error("couldn't make commando msg"); - } - - const dat = wasm_mem(buf, len) - module._free(buf); - return dat - } - - LNSocket.prototype.make_ping_msg = function _lnsocket_make_ping_msg(num_pong_bytes=1, ignored_bytes=1) { - const buflen = 32 - let len = 0; - const buf = module._malloc(buflen); - module.HEAPU8.set(Uint8Array, buf); - - if (!(len = lnsocket_make_ping_msg(buf, buflen, num_pong_bytes, ignored_bytes))) - throw new Error("couldn't make ping msg"); - - const dat = wasm_mem(buf, len) - module._free(buf); - return dat - } - - LNSocket.prototype.encrypt = function _lnsocket_encrypt(dat) { - const len = lnsocket_encrypt(this.ln, dat, dat.length) - if (len === 0) { - this.print_errors() - throw new Error("encrypt error") - } - const enc = wasm_mem(lnsocket_msgbuf(this.ln), len) - return enc - } - - LNSocket.prototype.decrypt = function _lnsocket_decrypt(dat) { - const len = lnsocket_decrypt(this.ln, dat, dat.length) - if (len === 0) { - this.print_errors() - throw new Error("decrypt error") - } - return wasm_mem(lnsocket_msgbuf(this.ln), len) - } - - LNSocket.prototype.write = function _lnsocket_write(dat) { - this.ws.send(this.encrypt(dat)) - } - - LNSocket.prototype.read = async function _lnsocket_read() { - const size = await this.read_header() - const enc = await this.read_all(size+16) - return this.decrypt(enc) - } - - LNSocket.prototype.make_default_initmsg = function _lnsocket_make_default_initmsg() { - const buflen = 1024 - let len = 0; - const buf = module._malloc(buflen); - module.HEAPU8.set(Uint8Array, buf); - - if (!(len = lnsocket_make_default_initmsg(buf, buflen))) - throw new Error("couldn't make initmsg"); - - const dat = wasm_mem(buf, len) - module._free(buf); - return dat - } - - LNSocket.prototype.perform_init = async function lnsocket_connect() { - await this.read() - const our_init = this.make_default_initmsg() - this.write(our_init) - } - - LNSocket.prototype.ping_pong = async function lnsocket_ping_pong() { - const pingmsg = this.make_ping_msg() - this.write(pingmsg) - return await this.read() - } - - LNSocket.prototype.disconnect = function lnsocket_disconnect() { - if (this.connected === true && this.ws) { - this.ws.close() - return true - } - return false - } - - LNSocket.prototype.destroy = function _lnsocket_destroy() { - this.disconnect() - lnsocket_destroy(this.ln) - } - - function handle_connect(ln, node_id, host) { - const ws = new SocketImpl(host) - return new Promise((resolve, reject) => { - const timeout = ln.opts.timeout || DEFAULT_TIMEOUT - const timer = setTimeout(reject, timeout); - - ws.ondata((v) => { - ln.queue.push(v) - }); - - ws.addEventListener('open', function(ev) { - ln.ws = ws - ln.connected = true - clearTimeout(timer) - resolve(ws) - }); - - ws.addEventListener('close', function(ev) { - ln.connected = false - }); - }) - } - - return LNSocket -} - -Module.init = Module.lnsocket_init = lnsocket_init diff --git a/js/lnsocket.wasm b/js/lnsocket.wasm deleted file mode 100755 index 59c3bb0..0000000 Binary files a/js/lnsocket.wasm and /dev/null differ diff --git a/web/js/main.js b/js/main.js similarity index 100% rename from web/js/main.js rename to js/main.js diff --git a/web/js/model.js b/js/model.js similarity index 100% rename from web/js/model.js rename to js/model.js diff --git a/web/js/noble-secp256k1.js b/js/noble-secp256k1.js similarity index 100% rename from web/js/noble-secp256k1.js rename to js/noble-secp256k1.js diff --git a/web/js/nostr.js b/js/nostr.js similarity index 100% rename from web/js/nostr.js rename to js/nostr.js diff --git a/js/qrcode.min.js b/js/qrcode.min.js deleted file mode 100644 index 993e88f..0000000 --- a/js/qrcode.min.js +++ /dev/null @@ -1 +0,0 @@ -var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this.parsedData=[];for(var b=[],d=0,e=this.data.length;e>d;d++){var f=this.data.charCodeAt(d);f>65536?(b[0]=240|(1835008&f)>>>18,b[1]=128|(258048&f)>>>12,b[2]=128|(4032&f)>>>6,b[3]=128|63&f):f>2048?(b[0]=224|(61440&f)>>>12,b[1]=128|(4032&f)>>>6,b[2]=128|63&f):f>128?(b[0]=192|(1984&f)>>>6,b[1]=128|63&f):b[0]=f,this.parsedData=this.parsedData.concat(b)}this.parsedData.length!=this.data.length&&(this.parsedData.unshift(191),this.parsedData.unshift(187),this.parsedData.unshift(239))}function b(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=[]}function i(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=f;f++){var h=0;switch(b){case d.L:h=l[f][0];break;case d.M:h=l[f][1];break;case d.Q:h=l[f][2];break;case d.H:h=l[f][3]}if(h>=e)break;c++}if(c>l.length)throw new Error("Too long data");return c}function s(a){var b=encodeURI(a).toString().replace(/\%[0-9a-fA-F]{2}/g,"a");return b.length+(b.length!=a?3:0)}a.prototype={getLength:function(){return this.parsedData.length},write:function(a){for(var b=0,c=this.parsedData.length;c>b;b++)a.put(this.parsedData[b],8)}},b.prototype={addData:function(b){var c=new a(b);this.dataList.push(c),this.dataCache=null},isDark:function(a,b){if(0>a||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){this.makeImpl(!1,this.getBestMaskPattern())},makeImpl:function(a,c){this.moduleCount=4*this.typeNumber+17,this.modules=new Array(this.moduleCount);for(var d=0;d=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=b.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,c)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(this.modules[a+c][b+d]=c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?!0:!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=f.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=g;g++)for(var h=-2;2>=h;h++)this.modules[d+g][e+h]=-2==g||2==g||-2==h||2==h||0==g&&0==h?!0:!1}},setupTypeNumber:function(a){for(var b=f.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(1&b>>c);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=f.getBCHTypeInfo(c),e=0;15>e;e++){var g=!a&&1==(1&d>>e);6>e?this.modules[e][8]=g:8>e?this.modules[e+1][8]=g:this.modules[this.moduleCount-15+e][8]=g}for(var e=0;15>e;e++){var g=!a&&1==(1&d>>e);8>e?this.modules[8][this.moduleCount-e-1]=g:9>e?this.modules[8][15-e-1+1]=g:this.modules[8][15-e-1]=g}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,g=0,h=this.moduleCount-1;h>0;h-=2)for(6==h&&h--;;){for(var i=0;2>i;i++)if(null==this.modules[d][h-i]){var j=!1;g>>e));var k=f.getMask(b,d,h-i);k&&(j=!j),this.modules[d][h-i]=j,e--,-1==e&&(g++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},b.PAD0=236,b.PAD1=17,b.createData=function(a,c,d){for(var e=j.getRSBlocks(a,c),g=new k,h=0;h8*l)throw new Error("code length overflow. ("+g.getLengthInBits()+">"+8*l+")");for(g.getLengthInBits()+4<=8*l&&g.put(0,4);0!=g.getLengthInBits()%8;)g.putBit(!1);for(;;){if(g.getLengthInBits()>=8*l)break;if(g.put(b.PAD0,8),g.getLengthInBits()>=8*l)break;g.put(b.PAD1,8)}return b.createBytes(g,e)},b.createBytes=function(a,b){for(var c=0,d=0,e=0,g=new Array(b.length),h=new Array(b.length),j=0;j=0?p.get(q):0}}for(var r=0,m=0;mm;m++)for(var j=0;jm;m++)for(var j=0;j=0;)b^=f.G15<=0;)b^=f.G18<>>=1;return b},getPatternPosition:function(a){return f.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case e.PATTERN000:return 0==(b+c)%2;case e.PATTERN001:return 0==b%2;case e.PATTERN010:return 0==c%3;case e.PATTERN011:return 0==(b+c)%3;case e.PATTERN100:return 0==(Math.floor(b/2)+Math.floor(c/3))%2;case e.PATTERN101:return 0==b*c%2+b*c%3;case e.PATTERN110:return 0==(b*c%2+b*c%3)%2;case e.PATTERN111:return 0==(b*c%3+(b+c)%2)%2;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new i([1],0),c=0;a>c;c++)b=b.multiply(new i([1,g.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case c.MODE_NUMBER:return 10;case c.MODE_ALPHA_NUM:return 9;case c.MODE_8BIT_BYTE:return 8;case c.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case c.MODE_NUMBER:return 12;case c.MODE_ALPHA_NUM:return 11;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case c.MODE_NUMBER:return 14;case c.MODE_ALPHA_NUM:return 13;case c.MODE_8BIT_BYTE:return 16;case c.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||(0!=h||0!=i)&&g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,(0==j||4==j)&&(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},g={glog:function(a){if(1>a)throw new Error("glog("+a+")");return g.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return g.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},h=0;8>h;h++)g.EXP_TABLE[h]=1<h;h++)g.EXP_TABLE[h]=g.EXP_TABLE[h-4]^g.EXP_TABLE[h-5]^g.EXP_TABLE[h-6]^g.EXP_TABLE[h-8];for(var h=0;255>h;h++)g.LOG_TABLE[g.EXP_TABLE[h]]=h;i.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],k=0;g>k;k++)e.push(new j(h,i));return e},j.getRsBlockTable=function(a,b){switch(b){case d.L:return j.RS_BLOCK_TABLE[4*(a-1)+0];case d.M:return j.RS_BLOCK_TABLE[4*(a-1)+1];case d.Q:return j.RS_BLOCK_TABLE[4*(a-1)+2];case d.H:return j.RS_BLOCK_TABLE[4*(a-1)+3];default:return void 0}},k.prototype={get:function(a){var b=Math.floor(a/8);return 1==(1&this.buffer[b]>>>7-a%8)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(1&a>>>b-c-1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}};var l=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]],o=function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){function g(a,b){var c=document.createElementNS("http://www.w3.org/2000/svg",a);for(var d in b)b.hasOwnProperty(d)&&c.setAttribute(d,b[d]);return c}var b=this._htOption,c=this._el,d=a.getModuleCount();Math.floor(b.width/d),Math.floor(b.height/d),this.clear();var h=g("svg",{viewBox:"0 0 "+String(d)+" "+String(d),width:"100%",height:"100%",fill:b.colorLight});h.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xlink","http://www.w3.org/1999/xlink"),c.appendChild(h),h.appendChild(g("rect",{fill:b.colorDark,width:"1",height:"1",id:"template"}));for(var i=0;d>i;i++)for(var j=0;d>j;j++)if(a.isDark(i,j)){var k=g("use",{x:String(i),y:String(j)});k.setAttributeNS("http://www.w3.org/1999/xlink","href","#template"),h.appendChild(k)}},a.prototype.clear=function(){for(;this._el.hasChildNodes();)this._el.removeChild(this._el.lastChild)},a}(),p="svg"===document.documentElement.tagName.toLowerCase(),q=p?o:m()?function(){function a(){this._elImage.src=this._elCanvas.toDataURL("image/png"),this._elImage.style.display="block",this._elCanvas.style.display="none"}function d(a,b){var c=this;if(c._fFail=b,c._fSuccess=a,null===c._bSupportDataURI){var d=document.createElement("img"),e=function(){c._bSupportDataURI=!1,c._fFail&&_fFail.call(c)},f=function(){c._bSupportDataURI=!0,c._fSuccess&&c._fSuccess.call(c)};return d.onabort=e,d.onerror=e,d.onload=f,d.src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==",void 0}c._bSupportDataURI===!0&&c._fSuccess?c._fSuccess.call(c):c._bSupportDataURI===!1&&c._fFail&&c._fFail.call(c)}if(this._android&&this._android<=2.1){var b=1/window.devicePixelRatio,c=CanvasRenderingContext2D.prototype.drawImage;CanvasRenderingContext2D.prototype.drawImage=function(a,d,e,f,g,h,i,j){if("nodeName"in a&&/img/i.test(a.nodeName))for(var l=arguments.length-1;l>=1;l--)arguments[l]=arguments[l]*b;else"undefined"==typeof j&&(arguments[1]*=b,arguments[2]*=b,arguments[3]*=b,arguments[4]*=b);c.apply(this,arguments)}}var e=function(a,b){this._bIsPainted=!1,this._android=n(),this._htOption=b,this._elCanvas=document.createElement("canvas"),this._elCanvas.width=b.width,this._elCanvas.height=b.height,a.appendChild(this._elCanvas),this._el=a,this._oContext=this._elCanvas.getContext("2d"),this._bIsPainted=!1,this._elImage=document.createElement("img"),this._elImage.style.display="none",this._el.appendChild(this._elImage),this._bSupportDataURI=null};return e.prototype.draw=function(a){var b=this._elImage,c=this._oContext,d=this._htOption,e=a.getModuleCount(),f=d.width/e,g=d.height/e,h=Math.round(f),i=Math.round(g);b.style.display="none",this.clear();for(var j=0;e>j;j++)for(var k=0;e>k;k++){var l=a.isDark(j,k),m=k*f,n=j*g;c.strokeStyle=l?d.colorDark:d.colorLight,c.lineWidth=1,c.fillStyle=l?d.colorDark:d.colorLight,c.fillRect(m,n,f,g),c.strokeRect(Math.floor(m)+.5,Math.floor(n)+.5,h,i),c.strokeRect(Math.ceil(m)-.5,Math.ceil(n)-.5,h,i)}this._bIsPainted=!0},e.prototype.makeImage=function(){this._bIsPainted&&d.call(this,a)},e.prototype.isPainted=function(){return this._bIsPainted},e.prototype.clear=function(){this._oContext.clearRect(0,0,this._elCanvas.width,this._elCanvas.height),this._bIsPainted=!1},e.prototype.round=function(a){return a?Math.floor(1e3*a)/1e3:a},e}():function(){var a=function(a,b){this._el=a,this._htOption=b};return a.prototype.draw=function(a){for(var b=this._htOption,c=this._el,d=a.getModuleCount(),e=Math.floor(b.width/d),f=Math.floor(b.height/d),g=[''],h=0;d>h;h++){g.push("");for(var i=0;d>i;i++)g.push('');g.push("")}g.push("
"),c.innerHTML=g.join("");var j=c.childNodes[0],k=(b.width-j.offsetWidth)/2,l=(b.height-j.offsetHeight)/2;k>0&&l>0&&(j.style.margin=l+"px "+k+"px")},a.prototype.clear=function(){this._el.innerHTML=""},a}();QRCode=function(a,b){if(this._htOption={width:256,height:256,typeNumber:4,colorDark:"#000000",colorLight:"#ffffff",correctLevel:d.H},"string"==typeof b&&(b={text:b}),b)for(var c in b)this._htOption[c]=b[c];"string"==typeof a&&(a=document.getElementById(a)),this._android=n(),this._el=a,this._oQRCode=null,this._oDrawing=new q(this._el,this._htOption),this._htOption.text&&this.makeCode(this._htOption.text)},QRCode.prototype.makeCode=function(a){this._oQRCode=new b(r(a,this._htOption.correctLevel),this._htOption.correctLevel),this._oQRCode.addData(a),this._oQRCode.make(),this._el.title=a,this._oDrawing.draw(this._oQRCode),this.makeImage()},QRCode.prototype.makeImage=function(){"function"==typeof this._oDrawing.makeImage&&(!this._android||this._android>=3)&&this._oDrawing.makeImage()},QRCode.prototype.clear=function(){this._oDrawing.clear()},QRCode.CorrectLevel=d}(); \ No newline at end of file diff --git a/js/tipjar.js b/js/tipjar.js deleted file mode 100644 index e06837f..0000000 --- a/js/tipjar.js +++ /dev/null @@ -1,172 +0,0 @@ -async function make_request(method, rune, params) { - const LNSocket = await lnsocket_init() - const ln = LNSocket() - - ln.genkey() - await ln.connect_and_init("03f3c108ccd536b8526841f0a5c58212bb9e6584a1eb493080e7c1cc34f82dad71", "wss://cln.jb55.com:443") - - const {result} = await ln.rpc({ rune, method, params }) - - ln.disconnect() - return result -} - -function fetch_tipjar_summary() { - const rune = "5sgpXcVRMy19h2Ai9LiklJ7jI_J3qNnnG36wvyViqR49OTQmbWV0aG9kPW9mZmVyLXN1bW1hcnkmcG5hbWVkZXNjcmlwdGlvbj1AZGFtdXMtYW5kcm9pZCZwbmFtZWxpbWl0PTU=" - return make_request("offer-summary", rune, { - offerid: "2043536dfec68d559102f73510927622812a230cfdda079e96fccbfe35a96d11", - description: "@damus-android", - limit: 5 - }) -} - -function make_invoice(description) { - const rune = "LZwGZJO7wZgmoScFQb5reZ0Ii8qPKCeUfTb-UcbDxWw9MTImbWV0aG9kPWludm9pY2U=" - description = (description && `${description} @damus-android`) || "@damus-android donation" - return make_request("invoice", rune, { - amount_msat: "any", - label: `damus-android-${new Date().getTime()}`, - description: description - }) -} - -function make_qrcode(dat) { - const link = dat.toUpperCase() - document.querySelector("#qrcode").innerHTML = "" - const qr = new QRCode("qrcode", { - text: link, - width: 256, - height: 256, - colorDark : "#000000", - colorLight : "#ffffff", - correctLevel : QRCode.CorrectLevel.L - }) -} - -async function click_make_invoice(el) { - const offerdata = document.querySelector("#offerdata") - const tipjar_img = document.querySelector("#tipjar-offer-qr") - - const note = prompt("Leave a note!", "") - - const invoice = await make_invoice(note) - - make_qrcode("LIGHTNING:" + invoice.bolt11) - document.querySelector("#bolt12").href = "lightning:" + invoice.bolt11 - - el.style.display = "none"; -} - -async function copy_tip() { - const offer = document.querySelector("#offerdata").value.trim(); - try { - await navigator.clipboard.writeText(offer) - alert("Invoice copied to clipboard!") - } catch(err) { - console.log("clipboard copy error", err) - document.querySelector("#offerdata").style.display = "block" - } -} - -async function go() { - const summary = await fetch_tipjar_summary() - - const el = document.querySelector("#tipjar-summary") - const bolt12 = document.querySelector("#bolt12") - - make_qrcode(bolt12.href) - el.innerHTML = render_tips(summary) -} - -function render_tips(res) { - const total_sats = res.total_msatoshi / 1000 - const goal = 3000000 - const perc = `${((total_sats / goal) * 100).toPrecision(2)}%` - const total_fmt = `${format_amount(total_sats)} / ${format_amount(goal)} sats goal (${perc})` - return ` -

Total: ${total_fmt}

-
-
-
-
Recent Donors
- ${render_table(res.paid_invoices)} -
Top Donors
- ${render_table(res.top_donors)} - ` -} - -function render_table(invoices) -{ - return ` - - - - - - - - - - ${invoices.map(render_tip).join("\n")} - -
NoteAmount
- ` -} - -function format_amount(amt) -{ - return amt.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); -} - -function render_tip(tip) -{ - let note = tip.payer_note ? tip.payer_note : (tip.description || "Anonymous") - note = note.replace("@damus-android", "") - const amount = format_amount(tip.amount_msat / 1000) - const now = Math.floor(new Date().getTime() / 1000) - const date = time_delta(now * 1000, tip.paid_at * 1000) - - return ` - - ${note} - ${amount} sats - ${date} - - ` -} - -function time_delta(current, previous) { - var msPerMinute = 60 * 1000; - var msPerHour = msPerMinute * 60; - var msPerDay = msPerHour * 24; - var msPerMonth = msPerDay * 30; - var msPerYear = msPerDay * 365; - - var elapsed = current - previous; - - if (elapsed < msPerMinute) { - return Math.round(elapsed/1000) + ' seconds ago'; - } - - else if (elapsed < msPerHour) { - return Math.round(elapsed/msPerMinute) + ' minutes ago'; - } - - else if (elapsed < msPerDay ) { - return Math.round(elapsed/msPerHour ) + ' hours ago'; - } - - else if (elapsed < msPerMonth) { - return Math.round(elapsed/msPerDay) + ' days ago'; - } - - else if (elapsed < msPerYear) { - return Math.round(elapsed/msPerMonth) + ' months ago'; - } - - else { - return Math.round(elapsed/msPerYear ) + ' years ago'; - } -} - -go() diff --git a/web/js/ui/fmt.js b/js/ui/fmt.js similarity index 100% rename from web/js/ui/fmt.js rename to js/ui/fmt.js diff --git a/web/js/ui/render.js b/js/ui/render.js similarity index 100% rename from web/js/ui/render.js rename to js/ui/render.js diff --git a/web/js/ui/safe-html.js b/js/ui/safe-html.js similarity index 100% rename from web/js/ui/safe-html.js rename to js/ui/safe-html.js diff --git a/web/js/ui/state.js b/js/ui/state.js similarity index 100% rename from web/js/ui/state.js rename to js/ui/state.js diff --git a/web/js/ui/util.js b/js/ui/util.js similarity index 100% rename from web/js/ui/util.js rename to js/ui/util.js diff --git a/web/js/unknowns.js b/js/unknowns.js similarity index 100% rename from web/js/unknowns.js rename to js/unknowns.js diff --git a/web/js/util.js b/js/util.js similarity index 100% rename from web/js/util.js rename to js/util.js diff --git a/key/bech32.js b/key/bech32.js deleted file mode 100644 index 5e28462..0000000 --- a/key/bech32.js +++ /dev/null @@ -1,168 +0,0 @@ -var ALPHABET = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l'; -var ALPHABET_MAP = {}; -for (var z = 0; z < ALPHABET.length; z++) { - var x = ALPHABET.charAt(z); - ALPHABET_MAP[x] = z; -} -function polymodStep(pre) { - var b = pre >> 25; - return (((pre & 0x1ffffff) << 5) ^ - (-((b >> 0) & 1) & 0x3b6a57b2) ^ - (-((b >> 1) & 1) & 0x26508e6d) ^ - (-((b >> 2) & 1) & 0x1ea119fa) ^ - (-((b >> 3) & 1) & 0x3d4233dd) ^ - (-((b >> 4) & 1) & 0x2a1462b3)); -} -function prefixChk(prefix) { - var chk = 1; - for (var i = 0; i < prefix.length; ++i) { - var c = prefix.charCodeAt(i); - if (c < 33 || c > 126) - return 'Invalid prefix (' + prefix + ')'; - chk = polymodStep(chk) ^ (c >> 5); - } - chk = polymodStep(chk); - for (var i = 0; i < prefix.length; ++i) { - var v = prefix.charCodeAt(i); - chk = polymodStep(chk) ^ (v & 0x1f); - } - return chk; -} -function convertbits(data, inBits, outBits, pad) { - var value = 0; - var bits = 0; - var maxV = (1 << outBits) - 1; - var result = []; - for (var i = 0; i < data.length; ++i) { - value = (value << inBits) | data[i]; - bits += inBits; - while (bits >= outBits) { - bits -= outBits; - result.push((value >> bits) & maxV); - } - } - if (pad) { - if (bits > 0) { - result.push((value << (outBits - bits)) & maxV); - } - } - else { - if (bits >= inBits) - return 'Excess padding'; - if ((value << (outBits - bits)) & maxV) - return 'Non-zero padding'; - } - return result; -} -function toWords(bytes) { - return convertbits(bytes, 8, 5, true); -} -function fromWordsUnsafe(words) { - var res = convertbits(words, 5, 8, false); - if (Array.isArray(res)) - return res; -} -function fromWords(words) { - var res = convertbits(words, 5, 8, false); - if (Array.isArray(res)) - return res; - throw new Error(res); -} -function getLibraryFromEncoding(encoding) { - var ENCODING_CONST; - if (encoding === 'bech32') { - ENCODING_CONST = 1; - } - else { - ENCODING_CONST = 0x2bc830a3; - } - function encode(prefix, words, LIMIT) { - LIMIT = LIMIT || 90; - if (prefix.length + 7 + words.length > LIMIT) - throw new TypeError('Exceeds length limit'); - prefix = prefix.toLowerCase(); - // determine chk mod - var chk = prefixChk(prefix); - if (typeof chk === 'string') - throw new Error(chk); - var result = prefix + '1'; - for (var i = 0; i < words.length; ++i) { - var x = words[i]; - if (x >> 5 !== 0) - throw new Error('Non 5-bit word'); - chk = polymodStep(chk) ^ x; - result += ALPHABET.charAt(x); - } - for (var i = 0; i < 6; ++i) { - chk = polymodStep(chk); - } - chk ^= ENCODING_CONST; - for (var i = 0; i < 6; ++i) { - var v = (chk >> ((5 - i) * 5)) & 0x1f; - result += ALPHABET.charAt(v); - } - return result; - } - function __decode(str, LIMIT) { - LIMIT = LIMIT || 90; - if (str.length < 8) - return str + ' too short'; - if (str.length > LIMIT) - return 'Exceeds length limit'; - // don't allow mixed case - var lowered = str.toLowerCase(); - var uppered = str.toUpperCase(); - if (str !== lowered && str !== uppered) - return 'Mixed-case string ' + str; - str = lowered; - var split = str.lastIndexOf('1'); - if (split === -1) - return 'No separator character for ' + str; - if (split === 0) - return 'Missing prefix for ' + str; - var prefix = str.slice(0, split); - var wordChars = str.slice(split + 1); - if (wordChars.length < 6) - return 'Data too short'; - var chk = prefixChk(prefix); - if (typeof chk === 'string') - return chk; - var words = []; - for (var i = 0; i < wordChars.length; ++i) { - var c = wordChars.charAt(i); - var v = ALPHABET_MAP[c]; - if (v === undefined) - return 'Unknown character ' + c; - chk = polymodStep(chk) ^ v; - // not in the checksum? - if (i + 6 >= wordChars.length) - continue; - words.push(v); - } - if (chk !== ENCODING_CONST) - return 'Invalid checksum for ' + str; - return { prefix: prefix, words: words }; - } - function decodeUnsafe(str, LIMIT) { - var res = __decode(str, LIMIT); - if (typeof res === 'object') - return res; - } - function decode(str, LIMIT) { - var res = __decode(str, LIMIT); - if (typeof res === 'object') - return res; - throw new Error(res); - } - return { - decodeUnsafe: decodeUnsafe, - decode: decode, - encode: encode, - toWords: toWords, - fromWordsUnsafe: fromWordsUnsafe, - fromWords: fromWords - }; -} - -const bech32 = getLibraryFromEncoding('bech32'); -const bech32m = getLibraryFromEncoding('bech32m'); diff --git a/key/index.html b/key/index.html deleted file mode 100644 index 5fcf681..0000000 --- a/key/index.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - damus key converter - - - - - - - - - - - - - - -
- - - damus - -
- - -
-

Key Converter

-

Convert a damus key to an old-style hex key

- - - - - - - -
- - - - - diff --git a/key/key.js b/key/key.js deleted file mode 100644 index 9dff6c1..0000000 --- a/key/key.js +++ /dev/null @@ -1,44 +0,0 @@ - -function hex_char(val) -{ - if (val < 10) - return String.fromCharCode(48 + val) - if (val < 16) - return String.fromCharCode(97 + val - 10) -} - -function hex_encode(buf) -{ - str = "" - for (let i = 0; i < buf.length; i++) { - const c = buf[i] - str += hex_char(c >> 4) - str += hex_char(c & 0xF) - } - return str -} - -function go() { - const el = document.querySelector("#damus-key") - const hex_el = document.querySelector("#hex-key") - const note_link_el = document.querySelector("#note-link") - const profile_link_el = document.querySelector("#profile-link") - - el.addEventListener("input", () => { - const decoded = bech32.decode(el.value) - const bytes = fromWords(decoded.words) - hex_el.value = hex_encode(bytes) - update_note_link(hex_el.value) - }); - - hex_el.addEventListener("input", () => { - update_note_link(hex_el.value) - }) - - function update_note_link(id) { - note_link_el.href = `nostr:e:${id}` - profile_link_el.href = `nostr:p:${id}` - } -} - -go() diff --git a/log/.envrc b/log/.envrc deleted file mode 100644 index 42644cd..0000000 --- a/log/.envrc +++ /dev/null @@ -1 +0,0 @@ -export PATH=$PWD:$PATH diff --git a/log/2022-08-02-introducing-damus-log.gmi b/log/2022-08-02-introducing-damus-log.gmi deleted file mode 100644 index 0f08dc7..0000000 --- a/log/2022-08-02-introducing-damus-log.gmi +++ /dev/null @@ -1,16 +0,0 @@ - -# The Damus Log - Powered by #nostr - -Hey there, Welcome to the damus log! A blog powered by... nostr! What does this mean!? What is nostr? Let's find out! - -nostr is what powers damus, an iOS nostr client we're working on. It's a fancy pants new internet protocol designed to be the email of social networks. Imagine if email was controlled by a single company. Everyone would have to use the same email client (probably something like gmail), and a single company would have complete control over all your data... everyone's data! - -This isn't good, this is why the internet today was originally built on these decentralized protocols. Things like websites and email are all available on different platforms, clients and servers. This freedom to pick and choose prevents any single company to have complete control over our data. - -nostr is an attempt to do the same for social networks themselves. It provides a censorship resistant, real-time database. Anyone can run a nostr relay and no single relay is in control of the data. It's quite ingenious if we say so ourselves. - -We like it so much we've made our blog nostr-powered! The comments below are from the nostr network. You can comment on it from the damus client itself! If you're interested in trying it out, try out the testflight at the bottom of our homepage: - -=> https://damus.io damus.io - -Looking forward to seeing you on nostr! diff --git a/log/2022-08-02-introducing-damus-log.html b/log/2022-08-02-introducing-damus-log.html deleted file mode 100644 index 391664a..0000000 --- a/log/2022-08-02-introducing-damus-log.html +++ /dev/null @@ -1,69 +0,0 @@ - - - - - - - - The Damus Log - - - - -
- -
-
- < The Damus Log -

The Damus Log - Powered by -#nostr

-

Hey there, Welcome to the damus log! A blog powered by… nostr! What -does this mean!? What is nostr? Let’s find out!

-

nostr is what powers damus, an iOS nostr client we’re working on. -It’s a fancy pants new internet protocol designed to be the email of -social networks. Imagine if email was controlled by a single company. -Everyone would have to use the same email client (probably something -like gmail), and a single company would have complete control over all -your data… everyone’s data!

-

This isn’t good, this is why the internet today was originally built -on these decentralized protocols. Things like websites and email are all -available on different platforms, clients and servers. This freedom to -pick and choose prevents any single company to have complete control -over our data.

-

nostr is an attempt to do the same for social networks themselves. It -provides a censorship resistant, real-time database. Anyone can run a -nostr relay and no single relay is in control of the data. It’s quite -ingenious if we say so ourselves.

-

We like it so much we’ve made our blog nostr-powered! The comments -below are from the nostr network. You can comment on it from the damus -client itself! If you’re interested in trying it out, try out the -testflight at the bottom of our homepage:

-

damus.io

-

Looking forward to seeing you on nostr!

- -

Comments

-
-
- - - -
- - diff --git a/log/2022-08-19-the-stuff-loads-better-release.gmi b/log/2022-08-19-the-stuff-loads-better-release.gmi deleted file mode 100644 index d154cf0..0000000 --- a/log/2022-08-19-the-stuff-loads-better-release.gmi +++ /dev/null @@ -1,51 +0,0 @@ - - -# v0.1.3 - The "Stuff Loads Better" Release - -It's that time again! A new damus release. This one fixes a bunch of annoying issues such as profiles not loading properly in some situations. We also do a much better job at caching profile pictures, so no more weird poppyness and wasting your cell data. - -If you're not on the testflight already, you can get it here: - -=> https://testflight.apple.com/join/CLwjLxWl Damus TestFlight - -This was the last release before lightning support, so next version will be exciting!! - -Anyways, here's the full changlog! - -``` -# Added - - - Support kind 42 chat messages (ArcadeCity). - - Friend icons next to names on some views. Check is friend. Arrows are friend-of-friends - - Load chat view first if content contains #chat - - Cancel button on search box - - Added profile picture cache - - Multiline DM messages - -# Changed - - - #hashtags now use the `t` tag instead of `hashtag` - - Clicking a chatroom quote reply will now expand it instead of jumping to it - - Clicking on a note will now always scroll it to the bottom - - Check note ids and signatures on every note - - use bech32 ids everywhere - - Don't animate scroll in chat view - - Post button is not shown if the content is only whitespace - -# Fixed - - - Fixed thread loading issue when clicking on boosts - - Fixed various issues with chatroom view - - Fix bug where sometimes nested navigation views weren't dismissed when tapping the tab bar - - Fixed minor carousel spacing issue on homescreen - - You can now reference users, notes hashtags in DMs - - Profile pics are now loaded in the background - - Limit post sizes to max 32,000 as an upper bound sanity limit. - - Missing profiles are now loaded everywhere - - No longer parse hashtags in urls - - Logging out now resets your keypair and actually logs out - - Copying text in DMs will now copy the decrypted text -``` - -=> https://damus.io Damus TestFlight - diff --git a/log/2022-08-19-the-stuff-loads-better-release.html b/log/2022-08-19-the-stuff-loads-better-release.html deleted file mode 100644 index 2accc00..0000000 --- a/log/2022-08-19-the-stuff-loads-better-release.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - The Damus Log - - - - -
- -
-
- < The Damus Log -

v0.1.3 - The “Stuff -Loads Better” Release

-

It’s that time again! A new damus release. This one fixes a bunch of -annoying issues such as profiles not loading properly in some -situations. We also do a much better job at caching profile pictures, so -no more weird poppyness and wasting your cell data.

-

If you’re not on the testflight already, you can get it here:

-

Damus -TestFlight

-

This was the last release before lightning support, so next version -will be exciting!!

-

Anyways, here’s the full changlog!

-
# Added
-
-     - Support kind 42 chat messages (ArcadeCity).
-     - Friend icons next to names on some views. Check is friend. Arrows are friend-of-friends
-     - Load chat view first if content contains #chat
-     - Cancel button on search box
-     - Added profile picture cache
-     - Multiline DM messages
-
-# Changed
-
-     - #hashtags now use the `t` tag instead of `hashtag`
-     - Clicking a chatroom quote reply will now expand it instead of jumping to it
-     - Clicking on a note will now always scroll it to the bottom
-     - Check note ids and signatures on every note
-     - use bech32 ids everywhere
-     - Don't animate scroll in chat view
-     - Post button is not shown if the content is only whitespace
-
-# Fixed
-
-     - Fixed thread loading issue when clicking on boosts
-     - Fixed various issues with chatroom view
-     - Fix bug where sometimes nested navigation views weren't dismissed when tapping the tab bar
-     - Fixed minor carousel spacing issue on homescreen
-     - You can now reference users, notes hashtags in DMs
-     - Profile pics are now loaded in the background
-     - Limit post sizes to max 32,000 as an upper bound sanity limit.
-     - Missing profiles are now loaded everywhere
-     - No longer parse hashtags in urls
-     - Logging out now resets your keypair and actually logs out
-     - Copying text in DMs will now copy the decrypted text
-

Damus TestFlight

- -

Comments

-
-
- - - -
- - diff --git a/log/2022-09-16-ok-can-you-guys-stop-developing-release.gmi b/log/2022-09-16-ok-can-you-guys-stop-developing-release.gmi deleted file mode 100644 index 3a5aee8..0000000 --- a/log/2022-09-16-ok-can-you-guys-stop-developing-release.gmi +++ /dev/null @@ -1,17 +0,0 @@ - -# v0.1.4 - Ok can you guys stop developing - -So someone had the smart idea[1] to create nostr chatrooms, so naturally damus should support these. I know I said the previous release would be the last release before lightning support, but chatrooms are pretty cool and I wanted to squeeze in an initial chatroom release. So here we are. - -I haven't added full chatroom support yet, like searching for and joining channels. The way that this release currently works is that if you see one of your friends chatting in a chatroom, you'll be able to reply to that chat from your home feed, or pop into the chatroom by clicking on the post. - -In the future I plan on having full chatroom support, probably something like how telegram displays their chatrooms. - -It's up on testflight now so check it out! - -Enjoy! - -=> https://anigma.io [1] Anigma - -=> https://testflight.apple.com/join/CLwjLxWl Damus TestFlight - diff --git a/log/2022-09-16-ok-can-you-guys-stop-developing-release.html b/log/2022-09-16-ok-can-you-guys-stop-developing-release.html deleted file mode 100644 index f63fc6f..0000000 --- a/log/2022-09-16-ok-can-you-guys-stop-developing-release.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - The Damus Log - - - - -
- -
-
- < The Damus Log -

v0.1.4 - Ok can you -guys stop developing

-

So someone had the smart idea[1] to create nostr chatrooms, so -naturally damus should support these. I know I said the previous release -would be the last release before lightning support, but chatrooms are -pretty cool and I wanted to squeeze in an initial chatroom release. So -here we are.

-

I haven’t added full chatroom support yet, like searching for and -joining channels. The way that this release currently works is that if -you see one of your friends chatting in a chatroom, you’ll be able to -reply to that chat from your home feed, or pop into the chatroom by -clicking on the post.

-

In the future I plan on having full chatroom support, probably -something like how telegram displays their chatrooms.

-

It’s up on testflight now so check it out!

-

Enjoy!

-

[1] Anigma

-

Damus -TestFlight

- -

Comments

-
-
- - - -
- - diff --git a/log/Makefile b/log/Makefile deleted file mode 100644 index 3377a2a..0000000 --- a/log/Makefile +++ /dev/null @@ -1,17 +0,0 @@ - -POSTS=$(wildcard *.gmi) -HTMLS=$(POSTS:.gmi=.html) - - -all: $(HTMLS) - -clean: fake - rm -f $(HTMLS) - -dist: all - rsync -avzP ./ charon:/www/damus.io/log/ - -%.html: %.gmi head.html tail.html - ./gmi2md < $< | pandoc -f markdown -t html -o - | cat head.html - tail.html > $@ - -.PHONY: fake diff --git a/log/comments.css b/log/comments.css deleted file mode 100644 index b9c60fa..0000000 --- a/log/comments.css +++ /dev/null @@ -1,69 +0,0 @@ - -.pfp { - width: 60px; - height: 60px; - margin: 0 15px 0 15px; - border-radius: 50%; -} - -.comment { - display: flex; - font-family: system-ui, sans; - margin-bottom: 20px; - flex-wrap: wrap; - align-items: center; -} - -.comment p { - background-color: rgba(255.0,255.0,255.0,0.1); - padding: 10px; - border-radius: 8px; - margin: 0; - width: 55%; -} - -.comment .info { - text-align: right; - width: 18%; - line-height: 0.8em; -} - -.quote { - border-left: 2px solid white; - margin-left: 10px; - padding: 10px; - background-color: rgba(255.0,255.0,255.0,0.1); - display: block; -} - -.comment .info span { - font-size: 11px; - color: rgba(255.0,255.0,255.0,0.7); -} - -@media (max-width: 800px){ - /* Reverse the order of elements in the user comments, - so that the avatar and info appear after the text. */ - .comment .info { - order: 2; - width: 50%; - text-align: left; - } - - .pfp { - order: 1; - margin: 0 15px 0 0; - } - - .comment { - padding: 10px; - border-radius: 8px; - background-color: rgba(255.0,255.0,255.0,0.1); - } - - .comment p { - order: 3; - margin-top: 10px; - width: 100%; - } -} diff --git a/log/comments.js b/log/comments.js deleted file mode 100644 index 6855eaa..0000000 --- a/log/comments.js +++ /dev/null @@ -1,177 +0,0 @@ - -function uuidv4() { - return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => - (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) - ); -} - - -async function comments_init(thread) -{ - const relay = await Relay("wss://relay.damus.io") - const now = (new Date().getTime()) / 1000 - const model = {events: [], profiles: {}} - const comments_id = uuidv4() - const profiles_id = uuidv4() - - model.pool = relay - model.el = document.querySelector("#comments") - - relay.subscribe(comments_id, {kinds: [1], "#e": [thread]}) - - relay.event = (sub_id, ev) => { - if (sub_id === comments_id) { - if (ev.content !== "") - insert_event_sorted(model.events, ev) - if (model.realtime) - render_home_view(model) - } else if (sub_id === profiles_id) { - try { - model.profiles[ev.pubkey] = JSON.parse(ev.content) - } catch { - console.log("failed to parse", ev.content) - } - } - } - - relay.eose = async (sub_id) => { - if (sub_id === comments_id) { - handle_comments_loaded(profiles_id, model) - } else if (sub_id === profiles_id) { - handle_profiles_loaded(profiles_id, model) - } - } - - return relay -} - -function handle_profiles_loaded(profiles_id, model) { - // stop asking for profiles - model.pool.unsubscribe(profiles_id) - model.realtime = true - render_home_view(model) -} - -// load profiles after comment notes are loaded -function handle_comments_loaded(profiles_id, model) -{ - const pubkeys = model.events.reduce((s, ev) => { - s.add(ev.pubkey) - return s - }, new Set()) - const authors = Array.from(pubkeys) - - // load profiles - model.pool.subscribe(profiles_id, {kinds: [0], authors: authors}) -} - -function render_home_view(model) { - model.el.innerHTML = render_events(model) -} - -function render_events(model) { - const render = render_event.bind(null, model) - return model.events.map(render).join("\n") -} - -function render_event(model, ev) { - const profile = model.profiles[ev.pubkey] || { - name: "anon", - display_name: "Anonymous", - } - const delta = time_delta(new Date().getTime(), ev.created_at*1000) - return ` -
-
- ${render_name(ev.pubkey, profile)} - ${delta} -
- -

- ${format_content(ev.content)} -

-
- ` -} - -function convert_quote_blocks(content) -{ - const split = content.split("\n") - let blockin = false - return split.reduce((str, line) => { - if (line !== "" && line[0] === '>') { - if (!blockin) { - str += "" - blockin = true - } - str += sanitize(line.slice(1)) - } else { - if (blockin) { - blockin = false - str += "" - } - str += sanitize(line) - } - return str + "
" - }, "") -} - -function format_content(content) -{ - return convert_quote_blocks(content) -} - -function sanitize(content) -{ - if (!content) - return "" - return content.replaceAll("<","<").replaceAll(">",">") -} - -function get_picture(pk, profile) -{ - return sanitize(profile.picture) || "https://robohash.org/" + pk -} - -function render_name(pk, profile={}) -{ - const display_name = profile.display_name || profile.user - const username = profile.name || "anon" - const name = display_name || username - - return `
${sanitize(name)}
` -} - -function time_delta(current, previous) { - var msPerMinute = 60 * 1000; - var msPerHour = msPerMinute * 60; - var msPerDay = msPerHour * 24; - var msPerMonth = msPerDay * 30; - var msPerYear = msPerDay * 365; - - var elapsed = current - previous; - - if (elapsed < msPerMinute) { - return Math.round(elapsed/1000) + ' seconds ago'; - } - - else if (elapsed < msPerHour) { - return Math.round(elapsed/msPerMinute) + ' minutes ago'; - } - - else if (elapsed < msPerDay ) { - return Math.round(elapsed/msPerHour ) + ' hours ago'; - } - - else if (elapsed < msPerMonth) { - return Math.round(elapsed/msPerDay) + ' days ago'; - } - - else if (elapsed < msPerYear) { - return Math.round(elapsed/msPerMonth) + ' months ago'; - } - - else { - return Math.round(elapsed/msPerYear ) + ' years ago'; - } -} diff --git a/log/gmi2md b/log/gmi2md deleted file mode 100755 index 2513ffc..0000000 --- a/log/gmi2md +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/env sedef - -# gmi2md: Sed script to convert text/gemini to markdown. -# Based on v0.14.2 of the gemini spec. -# -# This script is dedicated to the public domain according to the terms of CC0: -# https://creativecommons.org/publicdomain/zero/1.0/ - -x -/^```/ { - x - /^```/ { - x - s/.*// - x - } - b -} -g - -/^=>/ { - s/[][()]/\\&/g - s/^=>\s*([^[:space:]]+)\s*$/[\1](\1)/ - s/^=>\s*([^[:space:]]+)\s+(.+)/[\2](\1)/ -} diff --git a/log/head.html b/log/head.html deleted file mode 100644 index e24ccbb..0000000 --- a/log/head.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - The Damus Log - - - - -
- -
-
- < The Damus Log diff --git a/log/img b/log/img deleted file mode 120000 index 8e83967..0000000 --- a/log/img +++ /dev/null @@ -1 +0,0 @@ -../img/ \ No newline at end of file diff --git a/log/index.html b/log/index.html deleted file mode 100644 index 4246a78..0000000 --- a/log/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - The Damus Log - - - - -
- -
-
- -

The Damus Log

- - -

Comments

-
-
- - - -
- - diff --git a/log/log.css b/log/log.css deleted file mode 100644 index ee4c94d..0000000 --- a/log/log.css +++ /dev/null @@ -1,167 +0,0 @@ -@import url('https://rsms.me/inter/inter.css'); - -.header { - display: flex; - margin: 50px 0 0 0; - flex-direction: column; - align-items: center; -} - -.logo { - margin-bottom: 0; - letter-spacing: -0.05em; -} - -.date { - font-size: 0.7em; - margin-left: 10px; - color: #eee; -} - -.logo img { - padding-right: 18px; - width: 60px; -} - -a { - font-family: -system-ui, sans-serif; - color: white; -} - -a:visited { - color: #eee; -} - -body { - color: white; - min-height: 800px; -} - -html { - line-height: 1.5; - font-size: 20px; - font-family: "Georgia", sans-serif; - - background: linear-gradient(45deg, rgba(28,85,255,1) 0%, rgba(127,53,171,1) 59%, rgba(255,11,214,1) 100%); -} -.container { - margin: 0 auto; - max-width: 36em; - hyphens: auto; - word-wrap: break-word; - text-rendering: optimizeLegibility; - font-kerning: normal; -} -@media (max-width: 600px) { - .container { - font-size: 0.9em; - padding: 1em; - } -} -@media print { - .container { - background-color: transparent; - color: black; - font-size: 12pt; - } - p, h2, h3 { - orphans: 3; - widows: 3; - } - h2, h3, h4 { - page-break-after: avoid; - } -} -p { - margin: 1em 0; -} -img { - max-width: 100%; -} -h1, h2, h3, h4, h5, h6 { - font-family: 'Inter', system-ui, sans-serif; - margin-top: 1.4em; -} -h5, h6 { - font-size: 1em; - font-style: italic; -} -h6 { - font-weight: normal; -} -ol, ul { - padding-left: 1.7em; - margin-top: 1em; -} -li > ol, li > ul { - margin-top: 0; -} -blockquote { - margin: 1em 0 1em 1.7em; - padding-left: 1em; - border-left: 2px solid #e6e6e6; - color: #606060; -} -code { - font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace; - font-size: 85%; - margin: 0; -} -pre { - margin: 1em 0; - overflow: auto; -} -pre code { - padding: 0; - overflow: visible; -} -.sourceCode { - background-color: transparent; - overflow: visible; -} -hr { - background-color: #1a1a1a; - border: none; - height: 1px; - margin: 1em 0; -} -table { - margin: 1em 0; - border-collapse: collapse; - width: 100%; - overflow-x: auto; - display: block; - font-variant-numeric: lining-nums tabular-nums; -} -table caption { - margin-bottom: 0.75em; -} -tbody { - margin-top: 0.5em; - border-top: 1px solid #1a1a1a; - border-bottom: 1px solid #1a1a1a; -} -th { - border-top: 1px solid #1a1a1a; - padding: 0.25em 0.5em 0.25em 0.5em; -} -td { - padding: 0.125em 0.5em 0.25em 0.5em; -} -header { - margin-bottom: 4em; - text-align: center; -} -#TOC li { - list-style: none; -} -#TOC a:not(:hover) { - text-decoration: none; -} -code{white-space: pre-wrap;} -span.smallcaps{font-variant: small-caps;} -span.underline{text-decoration: underline;} -div.column{display: inline-block; vertical-align: top; width: 50%;} -div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} -ul.task-list{list-style: none;} -.display.math{display: block; text-align: center; margin: 0.5rem auto;} diff --git a/log/nostr.js b/log/nostr.js deleted file mode 100644 index 1e5b70b..0000000 --- a/log/nostr.js +++ /dev/null @@ -1,73 +0,0 @@ - -function insert_event_sorted(evs, new_ev) { - for (let i = 0; i < evs.length; i++) { - const ev = evs[i] - - if (new_ev.id === ev.id) { - return false - } - - if (new_ev.created_at > ev.created_at) { - evs.splice(i, 0, new_ev) - return true - } - } - - evs.push(new_ev) - return true -} - -function Relay(relay, opts={}) -{ - if (!(this instanceof Relay)) - return new Relay(relay, opts) - - this.relay = relay - this.opts = opts - - const me = this - return new Promise((resolve, reject) => { - const ws = me.ws = new WebSocket(relay); - let resolved = false - ws.onmessage = (m) => { handle_nostr_message(me, m) } - ws.onclose = () => { me.close && me.close() } - ws.onerror = () => { me.error && me.error() } - ws.onopen = () => { - if (resolved) { - me.open.bind(me) - return - } - - resolved = true - resolve(me) - } - }) -} - -Relay.prototype.subscribe = function relay_subscribe(sub_id, ...filters) { - const tosend = ["REQ", sub_id, ...filters] - this.ws.send(JSON.stringify(tosend)) -} - -Relay.prototype.unsubscribe = function relay_unsubscribe(sub_id) { - const tosend = ["CLOSE", sub_id] - this.ws.send(JSON.stringify(tosend)) -} - -function handle_nostr_message(relay, msg) -{ - const data = JSON.parse(msg.data) - if (data.length >= 2) { - switch (data[0]) { - case "EVENT": - if (data.length < 3) - return - return relay.event && relay.event(data[1], data[2]) - case "EOSE": - return relay.eose && relay.eose(data[1]) - case "NOTICE": - return relay.note && relay.note(...data.slice(1)) - } - } -} - diff --git a/log/tail.html b/log/tail.html deleted file mode 100644 index bc00f0f..0000000 --- a/log/tail.html +++ /dev/null @@ -1,25 +0,0 @@ - -

Comments

-
-
- - - -
- - diff --git a/log/template-head.html b/log/template-head.html deleted file mode 100644 index c4a2bd0..0000000 --- a/log/template-head.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - The Damus Log - - diff --git a/log/template-tail.html b/log/template-tail.html deleted file mode 100644 index 5179ade..0000000 --- a/log/template-tail.html +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/privacy-policy.txt b/privacy-policy.txt deleted file mode 100644 index dec17fa..0000000 --- a/privacy-policy.txt +++ /dev/null @@ -1 +0,0 @@ -Damus doesn't store any information about you other than the posts which you make, which are published to the damus relay as well other relays if configured. diff --git a/web/.gitignore b/web/.gitignore deleted file mode 100644 index 6e92f57..0000000 --- a/web/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tags diff --git a/web/COPYING b/web/COPYING deleted file mode 100644 index 50bdff2..0000000 --- a/web/COPYING +++ /dev/null @@ -1,15 +0,0 @@ -damus.io: damus web client and other things -Copyright (C) 2022 William Casarin - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. - -You should have received a copy of the GNU Affero General Public License -along with this program. If not, see . diff --git a/web/Makefile b/web/Makefile deleted file mode 100644 index 7614d7b..0000000 --- a/web/Makefile +++ /dev/null @@ -1,17 +0,0 @@ - -all: fake - @echo "you don't need to build anything." - -tags: fake - find js -name '*.js' | grep -v noble-secp256k1 | xargs ctags > "$@" - -emojiregex: fake - @curl -sL 'https://raw.githubusercontent.com/mathiasbynens/emoji-test-regex-pattern/main/dist/latest/javascript.txt' - -dist: - rsync -avzP --delete ./ charon:/www/damus.io/web/ - -dist-staging: - rsync -avzP ./ charon:/www/damus.io/web-staging/ - -.PHONY: fake diff --git a/web/README.md b/web/README.md deleted file mode 100644 index f425002..0000000 --- a/web/README.md +++ /dev/null @@ -1,62 +0,0 @@ -# Damus Web - -Here lies the code for the Damus web app, a client for the Nostr protocol. The -goal of this client is to be a better version of Twitter, but not to reproduce -all of it's functionality. - -[Issue Tracker](https://todo.sr.ht/~tomtom/damus-web-issues) - -## Roadmap - -Here is what is confirmed for development. - - - [ ] Share event - - [ ] Profile view (with ability to follow user) - - [ ] Edit metadata (from profile view) - - [ ] Global timeline view - - [ ] Notifications view - - [ ] Settings view (with ability to configure relays) - - [ ] Multiple reaction picker - - [ ] Direct Messages (subject to discussion) - -## Contribution Guide - -There are rules to contributing to this client. Please ensure you read them -before making changes and supplying patch notes. - - - No transpilers. All source code should work out of the box. - - Keep source code organised. Refer to the folder structure. If you have a - question, ask it. - - Do not include your personal tools in the source code. Use your own scripts - outside of the project. This does not include build tools such as Make. - - Use tabs & write JS with snake_case. End of discussion. - - Do not include binary files. - - No NPM (and kin) environments. If you need a file from an external resource - mark the location in the "sources" file and add it to the repo. - - No frameworks. Learn the browser tools and write good code. - - No experimental browser APIs. - - Do not write animations in JavaScript, CSS only. Keep them short and snappy. - Animations should not be a forefront, but an enjoyable addition. - - All new & modified code should be properly documented. - - Source code should be readable in the browser. - -These rules are subject to discussion. - -## Style Guide - -TODO Write about the style guide. - -## Terminology - - * Sign Out - Not "log out", "logout", "log off", etc. - * Sign In - Not "login", "log in", "signin", "sign-in", etc. - * Share - Not "boosted", "retweeted", "repost", etc. - * Send - Not "tweet", "toot", "post", etc. - * Link - Not "share". - -## Known Issues - - * You cannot send events when running from an IP address that is not secure. - Work arounds are not known at this time. - - diff --git a/web/index.html b/web/index.html deleted file mode 100644 index 2f31054..0000000 --- a/web/index.html +++ /dev/null @@ -1,272 +0,0 @@ - - - - - - - - Damus - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
-
-
-

- Yo, Sup? - -

-

The blue bird experience for Nostr.

- -
-
- -
-
-
- -
- - -
-
- -
-
-
- -
-
-
- -
-
- -
- - - -
-
-
-
-
- -
- - - -
-
-
- -

-
-
-
-
- -
-
-
- -
-
-
-
-
-
-
- - - - - - - -