Compare commits

...

181 Commits

Author SHA1 Message Date
nym21 f5e5bbefb2 changelog: update 2024-12-04 11:22:28 +01:00
nym21 d4323fb5e0 website: dca sim: improve reactivity 2024-12-04 11:15:18 +01:00
nym21 8af1ddd10d website: moved more code to lc wrapper 2024-12-04 10:28:30 +01:00
nym21 62f6d9a413 website: lc: moved markers to container 2024-12-03 19:04:21 +01:00
nym21 783aed5826 website: start containing lc code in wrapper 2024-12-03 17:31:56 +01:00
k 141cd819a1 website: reorg 2024-12-02 10:03:41 +01:00
k 44fa96eb49 website: sim: wording 2024-11-28 21:52:40 +01:00
k 778b514b65 website: simulation: fix sats added 2024-11-28 18:36:22 +01:00
k afd58d69e4 website: simulation: fix 'days ago' 2024-11-28 18:34:01 +01:00
k 4af9849b2b website: simulation: small changes 2024-11-28 18:31:15 +01:00
k 4dac44e720 website: simulation: small fixes 2024-11-28 15:58:11 +01:00
k 71871901ef website: update 2024-11-27 18:36:43 +01:00
k d39e7584c0 website: update 2024-11-27 12:56:04 +01:00
k 4e9c5612ca website: small fixes 2024-11-25 11:28:28 +01:00
k c8510dd45b changelog: update 2024-11-23 16:18:57 +01:00
k c234c17352 general: snapshot 2024-11-23 16:17:06 +01:00
k cfae483d9d parser: fix gnericmap multi_insert_simple_average 2024-11-20 11:42:06 +01:00
k d01ea13de4 global: snapshot 2024-11-20 10:50:14 +01:00
k 9a73ee6952 readme: fix link 2024-11-15 13:44:14 +01:00
k 28eb9e8c17 readme: update 2024-11-15 13:41:16 +01:00
k 749c91f662 readme: removed the fluff 2024-11-15 13:15:30 +01:00
k 97ac17a12a website: delete useless logs 2024-11-11 15:23:07 +01:00
k 32fd4fa8ed website: big update 2024-11-11 15:20:31 +01:00
k 12fe4c6ba5 parser: fix metadata bug 2024-11-08 22:53:39 +01:00
k b1e9fd95ca readme: typos 2024-11-05 09:36:49 +01:00
k d83043d8f2 server: readd content disposition attachement if ext present 2024-11-04 12:44:15 +01:00
k 2abeca6220 readme: update 2024-11-04 12:35:48 +01:00
k 781810ed9c parser: databases: small changes 2024-11-04 11:09:54 +01:00
k 2142847de3 website: moved packages + added ratio charts to compare folders 2024-11-02 12:42:40 +01:00
k ca42c266ef website: update cohorts colors 2024-11-02 00:59:57 +01:00
k f258ef1011 website: readd ratio to individual cohort folders 2024-11-01 20:52:43 +01:00
k 38cb763fd3 website: add compare to liquidity 2024-11-01 20:47:23 +01:00
k 3fa78241ef parser: exit inside global defrag 2024-11-01 20:23:06 +01:00
k 3c7bc13be9 Merge branch 'main' of github.com:kibo-money/kibo 2024-11-01 20:20:54 +01:00
k 2441ca35b3 website: up signals + added compare folder to all groups 2024-11-01 20:19:43 +01:00
k 216a3977be parser: reactivate 'first_defragment' option 2024-10-31 11:39:36 +01:00
k 647a51af15 parser: fix defrag 2024-10-31 09:57:06 +01:00
k 530d4ce717 general: temp rollback 2024-10-30 19:22:42 +01:00
k e5d81b4d5c parser: added databases defragmentation 2024-10-30 19:13:41 +01:00
k 6eaeca1f3d parser: db: improve iter function 2024-10-29 19:38:52 +01:00
k 4220034eab parser: crates upgrade && remove ram from config 2024-10-29 15:22:44 +01:00
k 76a8ddd354 server: tried oxc vs swc, kept swc 2024-10-29 14:40:12 +01:00
k 0bad38a815 iterable: added custom version 2024-10-28 16:51:20 +01:00
k 48a8aad20e parser: AnyDataset DX improvements 2024-10-28 16:48:27 +01:00
k 36ad0b3014 parser: revert save logic 2024-10-27 12:10:22 +01:00
k 95fc103eaf parser: fix metadata versioning 2024-10-27 10:52:42 +01:00
k f5754780a8 global: snapshot 2024-10-26 16:41:38 +02:00
k 7114c3bdf9 general: fixes 2024-10-21 14:36:02 +02:00
k 5b9d599e83 global: snapshot 2024-10-20 18:31:43 +02:00
k ffa4871035 readme: update instances 2024-10-19 11:49:01 +02:00
k 01832ac139 server: add .json option to last value routes 2024-10-19 11:04:32 +02:00
k cb7ff2bb37 changelog: update 2024-10-19 10:46:00 +02:00
k 35dd194b28 general: snapshot 2024-10-19 10:34:12 +02:00
k 7dac857135 docker: snapshot 2024-10-17 19:53:00 +02:00
k 608ccafc70 server: add support for .json .csv and ?all=true 2024-10-16 18:38:43 +02:00
k 4cdc9ef9b3 changelog: update 2024-10-09 00:39:25 +02:00
k db60d4e453 parser: compress empty_address_data 2024-10-09 00:33:14 +02:00
k f5d427a04f parser: cargo cleanup 2024-10-08 22:37:36 +02:00
k e4893e446c cargo: update 2024-10-08 21:53:38 +02:00
k 79ffbf3d1d global: snapshot 2024-10-08 21:47:46 +02:00
k 068bb07d6e global: snapshot 2024-10-04 19:09:09 +02:00
k 1c9d118ba2 changelog: update 2024-10-03 18:37:00 +02:00
k 5308796bac parser: removed liquidity split for everything but all addresses 2024-10-03 17:38:43 +02:00
k 669205aa4d general: snapshot 2024-10-02 10:48:05 +02:00
k 9d2c2f7945 global: snapshot 2024-09-29 20:39:51 +02:00
k e3b44b0adb website: refactor 2024-09-24 17:13:29 +02:00
k 1a303a9c38 docker: init 2024-09-23 18:44:55 +02:00
k 2befa58fce global: add sell side risk ratio 2024-09-21 14:22:27 +02:00
k c8ded4ddb3 general: add /api/last route 2024-09-20 16:56:36 +02:00
k 7d211f74d1 website: fixes 2024-09-19 21:48:54 +02:00
k 0f95d41785 website: rm history log 2024-09-19 21:11:37 +02:00
k 6389b530d9 changelog: hide broken image links 2024-09-19 21:10:11 +02:00
k 412769ff03 general: fixes 2024-09-19 21:03:50 +02:00
k d2349741f7 changelog: update 2024-09-19 11:24:13 +02:00
k 821bf8d63a readme: update 2024-09-19 11:01:08 +02:00
k 7b296e4863 parser: price fetch fixes 2024-09-19 10:49:26 +02:00
k 1acfcf088c readme: update 2024-09-18 20:15:32 +02:00
k e9680afdff readme: update 2024-09-18 19:31:33 +02:00
k 9695f12322 server: create in dir if missing 2024-09-18 18:43:36 +02:00
k 4060b7457b index: update geyser url 2024-09-18 18:35:19 +02:00
k a68344959d website: fix pathname on first load 2024-09-18 18:25:27 +02:00
k 41638d10bf server: add date-modified to datasets 2024-09-18 17:58:33 +02:00
k 9b4e166608 website: fixes 2024-09-18 16:56:55 +02:00
k 52a65fcad1 general: update 2024-09-18 00:14:53 +02:00
k da7c114d41 general: snapshot 2024-09-17 10:57:21 +02:00
k 62edee0860 readme 2024-09-17 00:22:51 +02:00
k 22ba5e7c94 assets: update 2024-09-16 23:45:24 +02:00
k 48e9a9c7dd website: add sw 2024-09-16 19:17:19 +02:00
k 9dbffb0c93 global: snapshot 2024-09-16 13:17:18 +02:00
k f95eb0f1c9 script: snapshot 2024-09-14 13:40:58 +02:00
k f3197c1af7 general: fixes 2024-09-14 11:47:02 +02:00
k 59f04c96c5 readme: update 2024-09-13 23:47:25 +02:00
k bf2034b80c global: snapshot 2024-09-13 22:59:20 +02:00
k deffaef2b5 rename: GUIDELINES to CONTRIBUTING 2024-09-11 22:52:53 +02:00
k 157ec003b7 remove: app 2024-09-11 22:47:26 +02:00
k ba4021ad73 global: snapshot 2024-09-10 23:15:13 +02:00
k 5edb8111a2 app: html version almost done 2024-09-10 09:39:06 +02:00
k e206b40468 general: snapshot 2024-08-26 01:23:48 +02:00
k 6ebd9320db app: folder reorg + tradingview notice 2024-08-08 17:11:58 +02:00
k 597a750fff app: unignore paths.d.ts to allow to run app without needing the server first 2024-08-08 09:48:36 +02:00
k 1273da6e71 changelog: update 2024-08-08 09:25:00 +02:00
k eb9b57eef4 parser: split txid_to_txdata db 2024-08-08 09:21:59 +02:00
k 5aaa05d579 parser: rm heed module 2024-08-06 19:52:59 +02:00
k 07abb0840b global: rm heed 2024-08-06 19:51:40 +02:00
k b8064510e3 parser: address_to_address_index: fix bad copy pasta 2024-08-05 12:07:20 +02:00
k a88d84e6e6 changelog: update 2024-08-05 11:58:17 +02:00
k c3c8f16793 parser: fix rpc call 2024-08-05 11:55:08 +02:00
k ce1fed8c16 parser: rm multisig db 2024-08-05 11:47:52 +02:00
k 9a8f5edd58 parser: fix binance time 2024-08-05 11:23:41 +02:00
k 992d45c8af server: update run.sh 2024-08-05 10:42:28 +02:00
k c646d6dc60 global: datasets compression via zstd 2024-08-05 00:44:46 +02:00
k 9067c28d24 parser: switch to biter 2024-08-03 15:17:57 +02:00
k afacea3fbb parser: reactivate bkp url for price fetching 2024-07-26 17:07:19 +02:00
k b68b016091 release: v0.3.0 2024-07-26 00:59:00 +02:00
k f1f4ad2188 global: fix: bugs 2024-07-26 00:44:17 +02:00
k d3d5e7f8d7 general: snapshot 2024-07-25 14:43:20 +02:00
k 0f8d7d5fe2 readme: add bkp api 2024-07-24 00:18:55 +02:00
k 63855e93a1 changelog: update v0.3.0 screenshot 2024-07-24 00:15:35 +02:00
k 07c1f5ab76 changelog: add v0.3.0 screenshot 2024-07-24 00:13:01 +02:00
k 4cd605fd34 global: update versions 2024-07-24 00:09:09 +02:00
k 8f5f28ede6 app: charts: add unit and price mode switch 2024-07-24 00:05:18 +02:00
k bf169d6954 app: add ivo to donators 2024-07-23 08:44:52 +02:00
k 1934c4bfda price: rm folder 2024-07-22 23:40:15 +02:00
k 5a7050df02 app: add chart scroll buttons 2024-07-22 19:06:58 +02:00
k 9871fdffc9 parser: add auto fetch price from main instance 2024-07-22 15:58:02 +02:00
k 232276d106 app: add height datasets 2024-07-22 11:08:58 +02:00
k 8b08a82f07 parser: add recap dataset 2024-07-21 22:59:54 +02:00
k 180d044f5d app: add SOPR 2024-07-21 00:51:36 +02:00
k 5611459f03 server: fix port 2024-07-20 23:18:49 +02:00
k 6eb4b51168 parser: cleanup 2024-07-20 23:15:36 +02:00
k a145b35ad1 general: snapshot 2024-07-20 23:13:41 +02:00
k d8a5b4a2e6 price: update 2024-07-20 13:32:58 +02:00
k 1f9d1542f1 parser: fix utxo panic after soft reset 2024-07-18 12:27:24 +02:00
k 4d23fdef61 general: snapshot 2024-07-18 09:16:18 +02:00
k fb978211ae price: push new 2024-07-16 11:48:41 +02:00
k 4fd67ebd99 app: add address size in sidebar when needed 2024-07-15 19:59:44 +02:00
k 0c899b2c16 parser: fix config file creation and remove panic 2024-07-15 19:43:37 +02:00
k 1be22713f9 parser: create config.toml if needed 2024-07-15 19:07:00 +02:00
k ad51edbe07 parser: setup clap 2024-07-15 18:52:29 +02:00
k 91f2427b44 app: add random chart button 2024-07-15 08:54:55 +02:00
k fbbb0920c5 parser: cohort ratio name changes 2024-07-13 00:40:47 +02:00
k 66bca200b4 parser: cointime forgot to add compute 2024-07-12 20:46:11 +02:00
k 5f11f15fe1 global: cointime ratios 2024-07-12 20:39:27 +02:00
k 96a50dd09a global: snapshot 2024-07-12 19:31:21 +02:00
k dcf605aa69 parser: percentiles fixed 2024-07-12 19:06:52 +02:00
k 6c7bd2a63a parser: percentiles 2024-07-12 18:08:27 +02:00
k 85835ac1d3 parser: add min date and height for percentile datasets 2024-07-12 17:38:22 +02:00
k 61038b07f9 parser: trying to fix ratio smas 2024-07-12 13:55:44 +02:00
k 68700925b0 parser: add 0 and 1 constant datasets 2024-07-12 12:55:46 +02:00
k 46f8e3bafd app: lazy load lean-qr 2024-07-12 12:47:05 +02:00
k 9077fee4d6 parser: add ratio for price smas 2024-07-12 12:02:57 +02:00
k 35fd5054aa general: snapshot 2024-07-12 08:35:41 +02:00
k 350c835873 parser: improve error message when price cannot be found 2024-07-10 21:34:55 +02:00
k 707ed7ec26 parser: update readme 2024-07-10 20:56:36 +02:00
k e159f18bfc parser: add node.args to git ignore 2024-07-10 20:51:27 +02:00
k 2308fa173a parser: allow node args 2024-07-10 20:51:03 +02:00
k 4a82ee0b05 parser: added ratio and co datasets 2024-07-10 18:34:01 +02:00
k 6976f5af0f general: snapshot 2024-07-10 18:33:24 +02:00
k 59cb524226 server: remove cloudflared restart from run script 2024-07-10 13:20:45 +02:00
k 37e1d2ba5b changelog: add mempool links 2024-07-08 20:47:36 +02:00
k 6c21e970aa changelog: update v0.2.0 date 2024-07-08 20:46:17 +02:00
k d3a4e917fb assets: add v0.2.0 screenshot 2024-07-08 20:43:56 +02:00
k 2481878892 release: v0.2.0 2024-07-08 19:57:30 +02:00
k 04359fbf31 general: snapshot 2024-07-08 17:31:51 +02:00
k 80ea12ed48 app: flatten lightweight-chart scripts 2024-07-06 12:05:11 +02:00
k 9d2d4b7d5f readme: update 2024-07-06 11:10:02 +02:00
k 3de2862655 readme: update 2024-07-06 10:23:54 +02:00
k abb4def848 readme: update 2024-07-06 09:08:11 +02:00
k 04decabc46 parser: fix ulimit only running in Mac OS 2024-07-05 22:23:00 +02:00
k 334ff52084 app: fix start date not being 1970-01-01 2024-07-05 18:28:01 +02:00
k a931ad7a1e general: snapshot 2024-07-05 18:03:53 +02:00
k 069311dcf3 general: snapshot 2024-07-03 20:40:35 +02:00
k b7e8cbea20 general: snapshot 2024-06-30 17:01:15 +02:00
k 9905eff383 readme: update 2024-06-25 22:29:27 +02:00
k 48320197f9 app: add geyser button 2024-06-25 22:06:48 +02:00
k 9c9a835f33 changelog: deleted image by mistake 2024-06-25 16:21:09 +02:00
k ec477b916b update: readme 2024-06-25 16:12:59 +02:00
k dc5a1fcb9a update: readme 2024-06-25 16:11:09 +02:00
k 20a51f980b general: snapshot 2024-06-25 14:46:23 +02:00
k 7604787fbb app: add mini window support 2024-06-24 06:50:23 +02:00
k e55b5195a9 release: v0.1.1 2024-06-24 05:14:52 +02:00
560 changed files with 36592 additions and 26849 deletions
+54 -2
View File
@@ -1,7 +1,59 @@
# Mac OS
.DS_Store
# To do
/charts
TODO.md
# Builds
dist
target
# I/O
in
out
.log
/datasets
/datasets2
/datasets_*
/price
*..*
/txout_*
/db
TODO.md
# Sync
.stfolder
# Copies
*\ copy*
# Ignored
ignore
# Scripts
/start-node.sh
# Editors
.vscode
.zed
# Configs
config.toml
# Flamegraph
flamegraph/
flamegraph.svg
# Benchmarks
benches
# Snapshots
snapshots*/
# Docker
docker/kibo
# Types
website/scripts/types/paths.d.ts
# Misc
OPENSATS.md
+247 -3
View File
@@ -1,6 +1,232 @@
# Changelog
## v. 0.1.1 - WIP
<!--
## v. 0.X.Y | WIP
![Image of the kibō Web App version 0.X.Y](./assets/v0.X.Y.jpg)
-->
## v. 0.5.0 | [873199](https://mempool.space/block/0000000000000000000270925aa6a565be92e13164565a3f7994ca1966e48050) - 2024/12/04
![Image of the kibō Web App version 0.5.0](./assets/v0.5.0.jpg)
## Datasets
- Added `Sell Side Risk Ratio` to all entities
- Added `Open`, `High` and `Low` datasets
- Added `Satoshis Per Dollar`
- Added `All Time High`
- Added `All Time High Date`
- Added `Days Since All Time High`
- Added `Max Days Between All Time Highs`
- Added `Max Years Between All Time Highs`
- Added `Drawdown`
- Added `Adjusted Value Created`, `Adjusted Value Destroyed` and `Adjusted Spent Output Profit Ratio` to all entities
- Added `Realized Profit To Loss Ratio` to all entities
- Added `Hash Price Min`
- Added `Hash Price Rebound`
- Removed all year datasets (25) in favor for epoch datasets (5), the former was too granular to be really useful
- Removed datasets split by liquidity for all datasets **already split by any address kind**, while fun to have, they took time to compute, ram, and space to store and no one was actually checking them
- Fixed a lot of values in split by liquidity datasets
## Website
- Updated the design yet again which made the website for something more minimal and easier on the eyes
- Added a *Save In Bitcoin* (DCA) simulation page
- ~Added a dashboard~ Added the latest values to the tree next to each option instead, while less values are visible at a time, it's much more readable and organised
- Added a library of PDFs
- Fixed service worker not passing 304 (not modified) response and instead serving cached responses
- Fixed history not being properly registered
- Fixed window being moveable on iOS when in standalone mode when it shouldn't be
- Added `Compare` section to all groups, to compare all datasets within a group
- Updated `Solid Signals` library, which had an important breaking change on the `createEffect` function which might bring some bugs
- Fixed some datasets paths
- A lot of code reorg and file splits
- Adopted a framework like approach to load pages while still being pure JS without a build step
- Probably more that was forgotten
## Parser
- Added a `/datasets/last` json file with all the latest values
- Added `--rpcconnect` parameter to the config
- Added handling of SIGINT and SIGTERM terminal signals which menas you can now safely CTRL+C or kill the parser while it's exporting
- Added config print at the start of the program
- Compressed `empty_address_data` struct to save space (should shave of between up to 50% of the `address_index_to_empty_address_data` database)
- Doubled the number of `txid_to_tx_data` databases from 4096 to 8192
- ~Added `--recompute_computed true` argument, to allow recomputation of computed datasets in case of a bug~ Buggy for now
- Fixed not saved arguments, not being processed properly
- Fixed bug in `generic_map.multi_insert_simple_average`
- Added defragmentation option `--first-defragment true` of databases to save space (which can save up to 50%)
- Fixed bug in the computation of averages in `GenericMap`
- Added support and paramer for cookie files with `--rpccookiefile`, and auto find if the path is `--datadir/.cookie`
- Increased number of retries and time between them when fetching price from exchanges APIs
## Server
- Fixed links in several places missing the `/api` part and thus not working
- Fixed broken last values routes
- Added support for the `/datasets/last` file via the `/api/last` route
- Added support for `.json` (won't change anything) and `.csv` (will download a csv file) extension at the end of datasets routes
- Added `all=true` query parameter to dataset routes to get to full history
## Biter
- Moved back to this repo
## v. 0.4.0 | [861950](https://mempool.space/block/00000000000000000000530d0e30ccf7deeace122dcc99f2668a06c6dad83629) - 2024/09/19
![Image of the kibō Web App version 0.4.0](./assets/v0.4.0.jpg)
### Brand
- **Satonomics** is now **kibō** 🎉
### Website
- Complete redesign of the website
- Rewrote the whole application and removed `node`/`npm`/`pnpm` dependencies in favor for pure `HTML`/`CSS`/`Javascript`
- Website is now served by the server
- Added Trading View attribution link to the settings frame and file in the lightweight charts folder
- Many other changes
### Parser
- Changed the block iterator from a custom version of [bitcoin-explorer](https://crates.io/crates/bitcoin-explorer) to the homemade [biter](https://crates.io/crates/biter) which allows the parser to run alongside `bitcoind`
- Added datasets compression thanks to [zstd](https://crates.io/crates/zstd) to reduce disk usage
- Use the Bitcoin RPC server for various calls instead of running cli commands and then parsing the JSON from the output
- **Important database changes that will need a full rescan**:
- Changed databases page size from 1MB to 4KB for improved disk usage
- Split txid_to_tx_data database in 4096 chunks (from 256) for improved disk usage
- Split address_index_to_X databases to chunks of 25_000 instead of 50_000
- Removed local Multisig database
- Updated the config, run with `-h` to see possible args
- Moved outputs from `/target/outputs` to `/out` to allow to run commands like `cargo clean` without side effects
- Various first run fixes
- Added to `-h` which arguments are saved, which is all of them at the time of writing
### Server
- Updated the code to support compressed binaries
- Added serving of the website
- Improved `Cache-Control` behavior
## v. 0.3.0 | [853930](https://mempool.space/block/00000000000000000002eb5e9a7950ca2d5d98bd1ed28fc9098aa630d417985d) - 2024/07/26
![Image of the Satonomics Web App version 0.3.0](./assets/v0.3.0.jpg)
### Parser
- Global
- Improved self-hosting by:
- Fixing an incredibly annoying bug that made the program panic because of a wrong utxo/address durable state after a or many new datasets were added/changed after a first successful parse of the chain
- Fixing a bug that would crash the program if launched for the first time ever
- Auto fetch prices from the main Satonomics instance if missing instead of only trying Kraken's and Binance's API which are limited to the last 16 hours
- Merged the core of `HeightMap` and `DateMap` structs into `GenericMap`
- Added `Height` struct and many others
- Reorganized outputs of both the parser and the server for ease of use and easier sync compatibility
- CLI
- Added an argument parser for improved UX with several options
- Datasets
- Added the following datasets for all entities:
- Value destroyed
- Value created
- Spent Output Profit Ratio (SOPR)
- Added the following ratio datasets and their variations to all prices {realized, moving average, any cointime, etc}:
- Market Price to {X}
- Market Price to {X} Ratio
- Market Price to {X} Ratio 1 Week SMA
- Market Price to {X} Ratio 1 Month SMA
- Market Price to {X} Ratio 1 Year SMA
- Market Price to {X} Ratio 1 Year SMA Momentum Oscillator
- Market Price to {X} Ratio 99th Percentile
- Market Price to {X} Ratio 99.5th Percentile
- Market Price to {X} Ratio 99.9th Percentile
- Market Price to {X} Ratio 1st Percentile
- Market Price to {X} Ratio 0.5th Percentile
- {X} 1% Top Probability
- {X} 0.5% Top Probability
- {X} 0.1% Top Probability
- {X} 1% Bottom Probability
- {X} 0.5% Bottom Probability
- {X} 0.1% Bottom Probability
- Added block metadatasets and their variants (raw/sum/average/min/max/percentiles):
- Block size
- Block weight
- Block VBytes
- Block interval
- Price
- Improved error message when price cannot be found
### App
- General
- Added chart scroll button for nice animations à la Wicked
- Added scale mode switch (Linear/Logarithmic) at the bottom right of all charts
- Added unit at the top left of all charts
- Added a backup API in case the main one fails or is offline
- Complete redesign of the datasets object
- Removed import of routes in JSON in favor for hardcoded typed routes in string format which resulted in:
- \+ A much lighter app
- \+ Better Lighthouse score
- \- Slower Typescript server
- Fixed datasets with null values crashing their fetch function
- Added a 'Go to a random chart' button in several places
- Chart
- Fixed series color being set to default ones after hovering the legend
- Fixed chart starting showing candlesticks and quickly switching to a line when it should've started directly with the line
- Separated the QRCode generator library from the main chunk and made it imported on click
- Fixed timescale changing on small screen after changing charts
- Folders
- Added the size in the "filename" of address cohorts grouped by size
- Favorites
- Added a 'favorite' and 'unfavorite' button at the bottom
- Settings
- Removed the horizontal scroll bar which was unintended
### Server
- Run file
- Only run with a watcher if `cargo watch` is available
- Removed id_to_path file in favor for only `paths.d.ts` in `app/src/types`
## v. 0.2.0 | [851286](https://mempool.space/block/0000000000000000000281ca7f1bf8c50702bfca168c7af1bdc67c977c1ac8ed) - 2024/07/08
![Image of the Satonomics Web App version 0.2.0](./assets/v0.2.0.jpg)
### App
- General
- Added the height version of all datasets and many optimizations to make them usable but only available on desktop and tablets for now
- Added a light theme
- Charts
- Added split panes in order to have the vertical axis visible for all datasets
- Added min and max values on the charts
- Fixed legend hovering on mobile not resetting on touch end
- Added "3 months" and yearly time scale setters (from year 2009 to today)
- Hide scrollbar of timescale setters and instead added scroll buttons to the legend only visible on desktop
- Improved Share/QR Code screen
- Changed all Area series to Line series
- Fixed horizontal scrollable legend not updating on preset change
- Performance
- Improved app's reactivity
- Added some chunk splitting for a faster initial load
- Global improvements that increased the Lighthouse's performance score
- Settings
- Finally made a proper component where you can chose the app's theme, between a moving or static background and its text opacity
- Added donations section with a leaderboard
- Added various links that are visible on the bottom side of the strip on desktop to mobile users
- Added install instructions when not installed for Apple users
- Misc
- Support mini window size, could be useful for embedded views
- Hopefully made scrollbars a little more subtle on WIndows and Linux, can't test
- Generale style updates
### Parser
- Fixed ulimit only being run in Mac OS instead of whenever the program is detected
## v. 0.1.1 | [849240](https://mempool.space/block/000000000000000000002b8653988655071c07bb5f7181c038f9326bc86db741) - 2024/06/24
![Image of the Satonomics Web App version 0.1.1](./assets/v0.1.1.jpg)
### Parser
@@ -9,7 +235,7 @@
### Server
- Added the chunk, date and time in the terminal logs
- Added the chunk, date and time of the request to the terminal logs
### App
@@ -18,6 +244,10 @@
- Added highlight effect to a legend by darkening the color of all the other series on the chart while hovering it with the mouse
- Added an API link in the legend for each dataset where applicable (when isn't generated locally)
- Save fullscreen preference in local storage and url
- Improved resize bar on desktop
- Changed resize button logo
- Changed the share button to visible on small screen too
- Improved share screen
- Fixed time range shifting not being the one in url params or saved in local storage
- Fixed time range shifting on series toggling via the legend
- Fixed time range shifting on fullscreen
@@ -27,13 +257,27 @@
- History
- Changed background for the sticky dates from blur to a solid color as it didn't appear properly in Firefox
- Build
- Added lazy loads to have split chunks after build
- Tried to add lazy loads to have split chunks after build, to have much faster load times and they worked great ! But they completely broke Safari on iOS, we can't have nice things
- Removed many libraries and did some things manually instead to improve build size
- Strip
- Temporarily removed the Home button on the strip bar on desktop as there is no landing page yet
- Settings
- Added version
- PWA
- Fixed background update
- Changed update check frequency to 1 minute (~1kb to fetch every minute which is very reasonable)
- Added a nice banner to ask the user to install the update
- Misc
- Removed tracker even though it was a very privacy friendly as it appeared to not be working properly
### Price
- Deleted old price datasets and their backups
## v. 0.1.0 | [848642](https://mempool.space/block/000000000000000000020be5761d70751252219a9557f55e91ecdfb86c4e026a) - 2024/06/19
![Image of the Satonomics Web App version 0.1.0](./assets/v0.1.0.jpg)
## v. 0.0.X | [835444](https://mempool.space/block/000000000000000000009f93907a0dd83c080d5585cc7ec82c076d45f6d7c872) - 2024/03/20
![Image of the Satonomics Web App version 0.0.X](./assets/v0.0.X.jpg)
+8
View File
@@ -0,0 +1,8 @@
# Guidelines
## Parser
- Avoid floats as much as possible
- Use structs like `WAmount` and `Price` for calculations
- **Only** use `WAmount.to_btc()` when inserting or computing inside a dataset. It is **very** expensive.
- No `Arc`, `Rc`, `Mutex` even from third party libraries, they're slower
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2024 Satonomics
Copyright (c) 2024 kibō
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+146 -39
View File
@@ -1,59 +1,166 @@
# SATONOMICS
<a href="https://kibo.money" target="_blank">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/kibo-money/kibo/main/assets/logo-long-text-dark.svg">
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/kibo-money/kibo/main/assets/logo-long-text-light.svg">
<img alt="kibō" src="https://raw.githubusercontent.com/kibo-money/kibo/main/assets/logo-long-text-light.svg" width="210" height="auto">
</picture>
</a>
## Description
TLDR: FOSS [glassnode](https://glassnode.com).
[**kibō**](https://kibo.money) (_hope_ in japanese) is primarily an open source Bitcoin Core data extractor and visualizer (similar to [Glassnode](https://glassnode.com)) which goal is to empower anybody with data about Bitcoin for free.
Satonomics is an open-source suite of tools that computes, distributes, and displays on-chain data, making it freely available for anyone to use.
The project is split in 3 parts:
The generated datasets are incredibly diverse and can be used for a wide range of purposes. Whether you're looking to conduct a health check on the network, gain insights into its current or past state, or leverage the data for trading purposes, these tools offer various charts, dashboards (Soon TM), and an extensive API to help you achieve your goals.
- First you have the extractor (parser), which parses the block data files from your Bitcoin Core node and computes a very wide range of datasets which are stored in compressed binary files
> For the curious, it takes at the very least 24 hours to parse all the blocks and compute all datasets. After that it will wait for a new block and take between 1 and 3 minutes to be up to date
- Then there is the website on which you can view, among other things, all datasets in various charts
- Finally there is the server which serves the website and the generated data via an [API](https://github.com/kibo-money/kibo/tree/main#endpoints)
To promote transparency and trust in the network, this project is committed to making on-chain data accessible and verifiable to all, without discrimination and is a great complimentary tool to [mempool.space](https://mempool.space).
Whether you're an enthusiast, a researcher, a miner, an analyst, a trader, a skeptic or just curious, there is something for everyone !
This project was created out of frustration by all the alternatives that were either very expensive and thus discriminatory and against bitcoin values or just very limited and none were open-source and verifiable. So while it's not the first tool trying to solve these problems, it's the first that is completely free, open-source and self-hostable.
If you are a user of [mempool.space](https://mempool.space), you'll find this to be very complimentary, as it offers a macro view of the chain over time instead of a detailed one.
## Instances
Web App:
- [app.satonomics.xyz](https://app.satonomics.xyz)
| URL | Type | Version | Status | Last Height | Up Time Ratio |
| ------------------------------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| [kibo.money](https://kibo.money) | Main | ![Version](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fkibo.money%2FCargo.toml&query=%24.package.version&style=for-the-badge&label=%20&color=%23db9e03) | ![Status](https://img.shields.io/uptimerobot/status/m797259009-043f6b92d4cc2deef7d13f50?style=for-the-badge&label=%20&up_color=%231cb454&down_color=%23e63636) | ![Height](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fkibo.money%2Fapi%2Flast-height.json&query=%24.value&style=for-the-badge&label=%20&color=%23f26610) | ![Ratio](https://img.shields.io/uptimerobot/ratio/m797259009-043f6b92d4cc2deef7d13f50?style=for-the-badge&label=%20&color=%232f73f1) |
| [backup.kibo.money](https://backup.kibo.money) | Backup | ![Version](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fbackup.kibo.money%2FCargo.toml&query=%24.package.version&style=for-the-badge&label=%20&color=%23db9e03) | ![Status](https://img.shields.io/uptimerobot/status/m797259013-bb29a8264fab8786fb80c5ed?style=for-the-badge&label=%20&up_color=%231cb454&down_color=%23e63636) | ![Height](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fbackup.kibo.money%2Fapi%2Flast-height.json&query=%24.value&style=for-the-badge&label=%20&color=%23f26610) | ![Ratio](https://img.shields.io/uptimerobot/ratio/m797259013-bb29a8264fab8786fb80c5ed?style=for-the-badge&label=%20&color=%232f73f1) |
| [preview.kibo.money](https://preview.kibo.money) | Dev | ![Version](https://img.shields.io/badge/dynamic/toml?url=https%3A%2F%2Fpreview.kibo.money%2FCargo.toml&query=%24.package.version&style=for-the-badge&label=%20&color=%23db9e03) | ![Status](https://img.shields.io/uptimerobot/status/m797869753-d40fc161bcb34624857a8082?style=for-the-badge&label=%20&up_color=%231cb454&down_color=%23e63636) | ![Height](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fpreview.kibo.money%2Fapi%2Flast-height.json&query=%24.value&style=for-the-badge&label=%20&color=%23f26610) | ![Ratio](https://img.shields.io/uptimerobot/ratio/m797869753-d40fc161bcb34624857a8082?style=for-the-badge&label=%20&color=%232f73f1) |
API:
- [api.satonomics.xyz](https://api.satonomics.xyz)
Please open an issue if you want to add another instance
## Structure
## Endpoints
- `parser`: The backbone of the project, it does most of the work by parsing and then computing datasets from the timechain.
- `server`: A small server which automatically creates routes to access through an API all created datasets.
- `app`: A web app which displays the generated datasets in various charts.
> If you running locally, you can replace `https://kibo.money` by `http://localhost:3110`
## Git
- [/](https://kibo.money/): Website
- [/api](https://kibo.money/api): A JSON with all available datasets, with their respective id and endpoint, better viewed in a Firefox based browser
- /api/TIMESCALE-to-ID: `TIMESCALE` can be `date` or `height`, and `ID` is the id with `_` replaced by `-`, let's take `date-to-close` (price at the end of each day) as an example
- [/api/date-to-close](https://kibo.money/api/date-to-close): current year's values in a json format
- [/api/date-to-close?chunk=2009](https://kibo.money/api/date-to-close?chunk=2009): values from the year 2009 in a json format
- [/api/date-to-close?all=true](https://kibo.money/api/date-to-close?all=true): all values in a json format
- You can also specify the extension to download a file, either `.json` or `.csv` to get the dataset in a CSV format; like so:
- [/api/date-to-close.csv](https://kibo.money/api/date-to-close.csv)
- [/api/date-to-close.csv?chunk=2009](https://kibo.money/api/date-to-close.csv?chunk=2009)
- [/api/date-to-close.csv?all=true](https://kibo.money/api/date-to-close.csv?all=true)
- [Repository](https://codeberg.org/satonomics/satonomics)
- [Issues](https://gitworkshop.dev/r/naddr1qq99xct5dahx7mtfvdesz9thwden5te0wp6hyurvv4ex2mrp0yhxxmmdqgsfw5dacngjlahye34krvgz7u0yghhjgk7gxzl5ptm9v6n2y3sn03srqsqqqaueek2h03/issues)
- [Proposals](https://gitworkshop.dev/r/naddr1qq99xct5dahx7mtfvdesz9thwden5te0wp6hyurvv4ex2mrp0yhxxmmdqgsfw5dacngjlahye34krvgz7u0yghhjgk7gxzl5ptm9v6n2y3sn03srqsqqqaueek2h03/proposals)
## Roadmap
## Goals
- **More Datasets/Charts**
- **Simulations**
- **Nostr integration**
- **API Documentation**
- **Descriptions**
- **Docker support**
- **Start9 support**
- Be the absolute best on-chain data source and app
- Have as many datasets and charts as possible
- Be self-hostable on cheap computers
- Be runnable on a machine with 8 GB RAM (16 GB RAM is already possible right now)
- Still being runnable 10 years from now
- By not relying on any third-party dependencies besides price APIs (which are and should be very common and easy to update)
- By **NOT** doing address labelling/tagging (which means **NO** exchange or any other individual address tracking), for that please use [mempool.space](https://mempool.space) or any other tool
## Setup
## Proof of Work
### Requirements
Aka: Previous iterations
- At least 16 GB of RAM
- 1 TB of free space (will use 70% of that without defragmentation and 40% after)
- A running instance of bitcoin-core with:
- `-txindex=1`
- `-blocksxor=0`
- RPC credentials
- Example: `bitcoind -datadir="$HOME/.bitcoin" -blocksonly -txindex=1 -blocksxor=0`
- Git
The initial idea was totally different yet morphed over time into what it is today: a fully FOSS self-hostable on-chain data generator
### Manual
- https://github.com/drgarlic/satonomics
- https://github.com/drgarlic/satonomics-parser
- https://github.com/drgarlic/satonomics-explorer
- https://github.com/drgarlic/satonomics-server
- https://github.com/drgarlic/satonomics-app
- https://github.com/drgarlic/bitalisys
- https://github.com/drgarlic/bitesque-app
- https://github.com/drgarlic/bitesque-back
- https://github.com/drgarlic/bitesque-front
- https://github.com/drgarlic/bitesque-assets
- https://github.com/drgarlic/syf
_Mac OS and Linux only, Windows is unsupported_
First we need to install Rust (https://www.rust-lang.org/tools/install)
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
```
If you already had Rust installed you could update it just in case
```bash
rustup update
```
> If you're on Ubuntu you'll probably also need to install `open-ssl` with
>
> ```bash
> sudo apt install libssl-dev pkg-config
> ```
Optionally, you can also install `cargo-watch` for the server to automatically restart it on file change, which will be triggered by new code and new datasets from the parser (https://github.com/watchexec/cargo-watch?tab=readme-ov-file#install)
```bash
cargo install cargo-watch --locked
```
Then you need to choose a path where all files related to **kibō** will live
```bash
cd ???
```
We can now clone the repository
```bash
git clone https://github.com/kibo-money/kibo.git
```
In a new terminal, go to the `parser`'s folder of the repository
```bash
cd ???/kibo/parser
```
Now we can finally start by running the parser, you need to use the `./run.sh` script instead of `cargo run -r` as we need to set various system variables for the program to run smoothly
For the first launch, the parser will need several information such as:
- `--datadir`: which is bitcoin data directory path, prefer `$HOME` to `~` as the latter might not work
Optionally you can also specify:
- `--rpccookiefile`: the path to the cookie file if not default
- `--rpcuser`: the username of the RPC credentials to talk to the bitcoin server if set
- `--rpcpassword`: the password of the RPC credentials if set
- `--rpcconnect`: if the bitcoin core server's IP is different than `localhost`
- `--rpcport`: if the port is different than `8332`
Everything will be saved in a `config.toml` file, which will allow you to simply run `./run.sh` next time
Here's an example
```bash
./run.sh --datadir=$HOME/Developer/bitcoin
```
In a **new** terminal, go to the `server`'s folder of the repository
```bash
cd ???/kibo/server
```
And start it also with the `run.sh` script instead of `cargo run -r`
```bash
./run.sh
```
Then the easiest to let others access your server is to use `cloudflared` which will also cache requests. For more information go to: https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/
## Donate
<img width="159" alt="image" src="https://github.com/user-attachments/assets/8bbb759f-4874-46cb-b093-b30cb30f5828">
[bc1q950q4ukpxxm6wjjkv6cpq8jzpazaxrrwftctkt](bitcoin:bc1q950q4ukpxxm6wjjkv6cpq8jzpazaxrrwftctkt)
<img width="159" alt="image" src="https://github.com/user-attachments/assets/745e39c7-be26-4f2a-90f2-54786e62ba35">
[lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4](lightning:lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4)
[Geyser Fund](https://geyser.fund/project/kibo/)
-9
View File
@@ -1,9 +0,0 @@
node_modules
charts
dist
dev-dist
.DS_Store
visualizer
# Local Netlify folder
.netlify
.wrangler
-10
View File
@@ -1,10 +0,0 @@
# Satonomics - App
## Description
A web app to view the generated datasets in various charts.
## Requirements
- `node`
- `pnpm`
-1
View File
@@ -1 +0,0 @@
/* /index.html
-372
View File
@@ -1,372 +0,0 @@
<!doctype html>
<html lang="en" class="overflow-hidden bg-black text-white">
<head>
<meta charset="utf-8" />
<title>Satonomics</title>
<meta
name="description"
content="An app to visualize Bitcoin on-chain data"
/>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link rel="manifest" href="/manifest.webmanifest" />
<meta name="theme-color" content="#0c0a09" />
<link
rel="icon"
type="image/png"
sizes="196x196"
href="/assets/favicon-196.png"
/>
<link rel="apple-touch-icon" href="/assets/apple-icon-180.png" />
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2048-2732.jpg"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2732-2048.jpg"
media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1668-2388.jpg"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2388-1668.jpg"
media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1536-2048.jpg"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2048-1536.jpg"
media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1488-2266.jpg"
media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2266-1488.jpg"
media="(device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1640-2360.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2360-1640.jpg"
media="(device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1668-2224.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2224-1668.jpg"
media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1620-2160.jpg"
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2160-1620.jpg"
media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1290-2796.jpg"
media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2796-1290.jpg"
media="(device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1179-2556.jpg"
media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2556-1179.jpg"
media="(device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1284-2778.jpg"
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2778-1284.jpg"
media="(device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1170-2532.jpg"
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2532-1170.jpg"
media="(device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1125-2436.jpg"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2436-1125.jpg"
media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1242-2688.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2688-1242.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-828-1792.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1792-828.jpg"
media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1242-2208.jpg"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-2208-1242.jpg"
media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-750-1334.jpg"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1334-750.jpg"
media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-640-1136.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-1136-640.jpg"
media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2048-2732.jpg"
media="(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2732-2048.jpg"
media="(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1668-2388.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2388-1668.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1536-2048.jpg"
media="(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2048-1536.jpg"
media="(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1488-2266.jpg"
media="(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2266-1488.jpg"
media="(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1640-2360.jpg"
media="(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2360-1640.jpg"
media="(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1668-2224.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2224-1668.jpg"
media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1620-2160.jpg"
media="(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2160-1620.jpg"
media="(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1290-2796.jpg"
media="(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2796-1290.jpg"
media="(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1179-2556.jpg"
media="(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2556-1179.jpg"
media="(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1284-2778.jpg"
media="(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2778-1284.jpg"
media="(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1170-2532.jpg"
media="(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2532-1170.jpg"
media="(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1125-2436.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2436-1125.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1242-2688.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2688-1242.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-828-1792.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1792-828.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1242-2208.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-2208-1242.jpg"
media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-750-1334.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1334-750.jpg"
media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-640-1136.jpg"
media="(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
/>
<link
rel="apple-touch-startup-image"
href="/assets/apple-splash-dark-1136-640.jpg"
media="(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
/>
</head>
<body style="font-size: 15px; line-height: 22px">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script src="/src/index.tsx" type="module"></script>
</body>
</html>
-48
View File
@@ -1,48 +0,0 @@
{
"name": "satonomics",
"description": "Satoshi Economics",
"version": "0.1.0",
"license": "MIT",
"type": "module",
"scripts": {
"dev": "($npm_execpath outdated || read -p \"Press enter to ignore...\") && vite --host",
"build": "vite build",
"check": "tsc --noEmit --skipLibCheck --pretty",
"check-watch": "$npm_execpath check --watch",
"format": "prettier --write './src'",
"prod": "$npm_execpath run build && vite preview --host",
"pages-prod": "pnpm build && pnpm wrangler pages deploy ./dist",
"pages-dev": "pnpm build && pnpm wrangler pages deploy --branch dev ./dist",
"assets": "pnpm pwa-asset-generator ./public/logo/white.svg ./public/assets --index ./index.html --manifest ./public/manifest.webmanifest --icon-only --favicon --background \"linear-gradient(to right bottom, rgb(249, 115, 22), rgb(154, 52, 18))\" --padding \"min(15vh, 15vw)\" --path-override \"/assets\" && pnpm pwa-asset-generator ./public/logo/white.svg ./public/assets --index ./index.html --splash-only --background \"linear-gradient(to right bottom, rgb(249, 115, 22), rgb(154, 52, 18))\" --padding \"min(33vh, 33vw)\" --path-override \"/assets\" && pnpm pwa-asset-generator ./public/logo/white.svg ./public/assets --index ./index.html --splash-only --dark-mode --background \"#0c0a09\" --padding \"min(33vh, 33vw)\" --path-override \"/assets\""
},
"dependencies": {
"@leeoniya/ufuzzy": "^1.0.14",
"@solid-primitives/event-listener": "^2.3.3",
"@solid-primitives/intersection-observer": "^2.1.6",
"@solid-primitives/memo": "^1.3.8",
"@solid-primitives/resize-observer": "^2.0.25",
"lean-qr": "^2.3.4",
"lightweight-charts": "^4.1.6",
"solid-js": "^1.8.17"
},
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
"@iconify-json/tabler": "^1.1.114",
"@tailwindcss/container-queries": "^0.1.1",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"prettier": "^3.3.2",
"prettier-plugin-tailwindcss": "^0.6.5",
"pwa-asset-generator": "^6.3.1",
"rollup-plugin-visualizer": "^5.12.0",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.2",
"unplugin-auto-import": "^0.17.6",
"unplugin-icons": "^0.19.0",
"vite": "^5.3.1",
"vite-plugin-pwa": "^0.20.0",
"vite-plugin-solid": "^2.10.2",
"workbox-window": "^7.1.0",
"wrangler": "^3.61.0"
}
}
-6333
View File
File diff suppressed because it is too large Load Diff
-11
View File
@@ -1,11 +0,0 @@
/** @type {import("prettier").Options} */
export default {
plugins: [
'@ianvs/prettier-plugin-sort-imports',
'prettier-plugin-tailwindcss', // MUST come last
],
tailwindFunctions: ['classList'],
importOrder: ['<THIRD_PARTY_MODULES>', '', '^/?(~|src)/', '', '^[./]'],
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.
-17
View File
@@ -1,17 +0,0 @@
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" fill="black">
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,5.12904)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,0.129039)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,-4.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,-9.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,10.129)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1004 B

-17
View File
@@ -1,17 +0,0 @@
<svg width="100%" height="100%" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" fill="white">
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,5.12904)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,0.129039)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(1.14102,0,0,2.63158,-0.849652,-4.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,-9.87096)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
<g transform="matrix(0.285256,0,0,2.63158,8.78759,10.129)">
<rect x="4.25" y="3.751" width="14.023" height="1.52"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1004 B

-37
View File
@@ -1,37 +0,0 @@
{
"name": "Satonomics",
"short_name": "Satonomics",
"description": "Satoshi Economics",
"start_url": "/",
"display": "standalone",
"theme_color": "#0c0a09",
"background_color": "#0c0a09",
"lang": "en",
"scope": "/",
"icons": [
{
"src": "/assets/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/manifest-icon-192.maskable.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "/assets/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "/assets/manifest-icon-512.maskable.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}
-175
View File
@@ -1,175 +0,0 @@
import { createRWS } from "/src/solid/rws";
const texts = [
"satonomics",
"satonomics",
"satonomics",
"stay humble, stack sats",
"21 million",
"cold storage",
"utxo",
"satoshi nakamoto",
"hodl",
`don't trust, verify`,
"zap",
"bitcoin",
"lightning",
"nostr",
"freedom tech",
"2008/10/31",
"2009/01/03",
"2010/05/22",
"hodl!",
"Hal Finney",
"Vote for better money",
"gradually then suddenly",
"timechain",
"self custody",
"be your own bank",
"resistance money",
"foss",
];
export const LOCAL_STORAGE_MARQUEE_KEY = "bg-marquee";
export function Background({
marquee: on,
focused,
}: {
marquee: Accessor<boolean>;
focused: Accessor<boolean>;
}) {
createEffect(() => {
if (on()) {
localStorage.removeItem(LOCAL_STORAGE_MARQUEE_KEY);
} else {
localStorage.setItem(LOCAL_STORAGE_MARQUEE_KEY, "false");
}
});
return (
<>
<div class="absolute h-full w-full overflow-hidden opacity-[0.0333] will-change-auto">
<div class="-m-[2rem] -space-y-1 overflow-hidden md:-m-[1rem]">
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
<Line on={on} focused={focused} />
</div>
</div>
<div class="absolute h-full w-full opacity-10 mix-blend-multiply">
<Noise />
</div>
<div class="absolute h-full w-full opacity-10 mix-blend-hard-light">
<Noise />
</div>
</>
);
}
function Line({
on,
focused,
}: {
on: Accessor<boolean>;
focused: Accessor<boolean>;
}) {
const shuffled = shuffle([...texts]);
shuffled.pop();
const joined = shuffled.join(". ");
return (
<div class="select-none whitespace-nowrap">
<TextWrapper on={on} focused={focused} joined={joined} />
</div>
);
}
function TextWrapper({
joined,
on,
focused,
}: {
on: Accessor<boolean>;
focused: Accessor<boolean>;
joined: string;
}) {
const seconds = joined.length * 2;
const wasOnceOn = createRWS(false);
createEffect(() => {
if (!wasOnceOn() && on()) {
wasOnceOn.set(true);
}
});
return (
<p
class="inline-block px-2 text-[5dvh] font-black uppercase leading-none"
style={{
...(wasOnceOn()
? {
animation: `marquee ${seconds}s linear infinite`,
"animation-play-state": focused() && on() ? "running" : "paused",
}
: {}),
}}
>
{joined} {wasOnceOn() ? joined : undefined}
</p>
);
}
function shuffle<T>([...arr]: T[]): T[] {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr;
}
function Noise() {
return (
<svg
class="size-full"
viewBox="0 0 200 200"
preserveAspectRatio="none"
xmlns="http://www.w3.org/2000/svg"
>
<filter id="noiseFilter">
<feTurbulence
type="fractalNoise"
baseFrequency="3"
numOctaves="3"
stitchTiles="stitch"
/>
</filter>
<rect width="100%" height="100%" filter="url(#noiseFilter)" />
</svg>
);
}
-154
View File
@@ -1,154 +0,0 @@
import { createResizeObserver } from "@solid-primitives/resize-observer";
import { classPropToString } from "/src/solid/classes";
import { createRWS } from "/src/solid/rws";
export function Box({
flex = true,
absolute,
padded = true,
children,
dark,
overflowY,
}: {
flex?: boolean;
absolute?: "top" | "bottom";
padded?: boolean;
dark?: boolean;
overflowY?: boolean;
} & ParentProps) {
const maybeScrollable = createRWS<HTMLDivElement | undefined>(undefined);
const scrollable = createRWS(false);
const showLeftArrow = createRWS(false);
const showRightArrow = createRWS(false);
onMount(() => {
createResizeObserver(maybeScrollable, (_, el) => {
if (el !== maybeScrollable()) {
return;
}
scrollable.set(() => el.scrollWidth > el.clientWidth);
checkArrows();
});
});
function checkArrows() {
const offset = 20;
const target = maybeScrollable()!;
const left = target.scrollLeft;
const right = target.scrollWidth - target.scrollLeft - target.clientWidth;
showLeftArrow.set(() => left > offset);
showRightArrow.set(() => right > offset);
}
return (
<div
class={classPropToString([
"p-2",
absolute
? [
"absolute inset-x-0",
absolute === "top"
? "top-0"
: "pointer-events-none bottom-0 bg-gradient-to-b from-transparent to-black",
]
: "relative",
])}
>
<div
class={classPropToString([
"pointer-events-auto relative overflow-hidden rounded-xl border border-orange-200/10 shadow-md",
dark
? "bg-orange-100/5 backdrop-blur-sm"
: "bg-orange-200/10 backdrop-blur-md",
])}
>
<For
each={[
{
showArrow: showLeftArrow,
side: "left-0",
order: "",
buttonPadding: "pl-3 pr-2",
iconPadding: "pr-0.5",
scrollMultiplier: -1,
chevronIcon: IconTablerChevronLeft,
gradientDirection: "bg-gradient-to-r",
},
{
showArrow: showRightArrow,
side: "right-0",
order: "order-2",
buttonPadding: "pl-2 pr-3",
iconPadding: "pl-0.5",
scrollMultiplier: 1,
chevronIcon: IconTablerChevronRight,
gradientDirection: "bg-gradient-to-l",
},
]}
>
{(obj) => (
<Show when={scrollable() && obj.showArrow()}>
<div
class={[
obj.side,
"pointer-events-none absolute bottom-0 top-0 z-20 flex transition-opacity duration-200 ease-in-out",
].join(" ")}
>
<div
class={[
obj.order,
obj.buttonPadding,
"pointer-events-auto hidden h-full items-center bg-black/90 md:flex",
].join(" ")}
>
<button
onClick={() => {
maybeScrollable()?.scrollBy({
left: Math.floor(
maybeScrollable()!.clientWidth *
obj.scrollMultiplier *
0.8,
),
behavior: "smooth",
});
}}
class="rounded-full border border-orange-200/20 bg-black p-0.5 transition hover:scale-110 active:scale-100"
>
<Dynamic
component={obj.chevronIcon}
class={[`size-5 ${obj.iconPadding}`]}
/>
</button>
</div>
<div
class={[
obj.gradientDirection,
"h-full w-10 from-black/90 to-transparent",
].join(" ")}
/>
</div>
</Show>
)}
</For>
<div
ref={maybeScrollable.set}
onScroll={checkArrows}
class={classPropToString([
flex && "flex w-full space-x-2",
overflowY && "overflow-y-auto",
padded && "p-1.5",
])}
>
{children}
</div>
</div>
</div>
);
}
-13
View File
@@ -1,13 +0,0 @@
export function Button({
onClick,
children,
}: { onClick: VoidFunction } & ParentProps) {
return (
<button
class="group flex w-full flex-1 items-center justify-center rounded-lg px-2 py-1.5 hover:bg-orange-200/20 active:scale-95"
onClick={onClick}
>
{children}
</button>
);
}
@@ -1,102 +0,0 @@
import type { Generate } from "lean-qr";
import { chartState } from "/src/scripts/lightweightCharts/chart/state";
import { setTimeScale } from "/src/scripts/lightweightCharts/chart/time";
import { classPropToString } from "/src/solid/classes";
import { createRWS } from "/src/solid/rws";
export function Actions({
presets,
fullscreen,
qrcode,
}: {
presets: Presets;
qrcode: RWS<string>;
fullscreen?: RWS<boolean>;
}) {
const leanQRGenerate = createRWS<Generate | undefined>(undefined);
onMount(() => {
import("lean-qr").then((leanQR) => {
leanQRGenerate.set(() => leanQR.generate);
});
});
return (
<div class="flex space-x-1">
<Button
icon={() => IconTablerMaximize}
onClick={() => {
const range = chartState.range;
fullscreen?.set((b) => !b);
setTimeScale(range);
}}
classes="hidden md:block"
/>
<Button
icon={() => IconTablerShare}
disabled={() => !leanQRGenerate()}
onClick={() => {
let generate = leanQRGenerate();
if (generate) {
qrcode.set(() =>
generate(document.location.href).toDataURL({
on: [0xff, 0xff, 0xff, 0xff],
off: [0x00, 0x00, 0x00, 0x00],
}),
);
}
}}
classes="hidden md:block"
/>
<Button
colors={() =>
presets.selected().isFavorite()
? "text-amber-500 bg-amber-500/15 hover:bg-amber-500/30"
: ""
}
icon={() =>
presets.selected().isFavorite()
? IconTablerStarFilled
: IconTablerStar
}
onClick={() => presets.selected().isFavorite.set((b) => !b)}
/>
</div>
);
}
function Button({
icon,
colors,
onClick,
disabled,
classes,
}: {
icon: () => ValidComponent;
colors?: () => string;
onClick: VoidFunction;
disabled?: () => boolean;
classes?: string;
}) {
return (
<button
disabled={disabled?.()}
class={classPropToString([
colors?.() || (disabled?.() ? "" : "hover:bg-orange-200/15"),
!disabled?.() && "group",
classes,
"flex-none rounded-lg p-2 disabled:opacity-50",
])}
onClick={onClick}
>
<Dynamic
component={icon()}
class="size-[1.125rem] group-active:scale-90"
/>
</button>
);
}
@@ -1,33 +0,0 @@
import { cleanChart } from "/src/scripts/lightweightCharts/chart/clean";
import { renderChart } from "/src/scripts/lightweightCharts/chart/render";
export function Chart({
presets,
datasets,
legendSetter,
activeResources,
}: {
presets: Presets;
datasets: Datasets;
legendSetter: Setter<PresetLegend>;
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
}) {
onMount(() => {
createEffect(() => {
const preset = presets.selected();
untrack(() =>
renderChart({
datasets,
preset,
legendSetter,
activeResources,
}),
);
});
onCleanup(cleanChart);
});
return <div id="chart" class="h-full w-full cursor-crosshair" />;
}
@@ -1,134 +0,0 @@
import { createRWS } from "/src/solid/rws";
const transparency = "66";
export function Legend({
legend: legendList,
}: {
legend: Accessor<PresetLegend>;
}) {
const hovering = createRWS<SeriesLegend | undefined>(undefined);
let toggle = false;
return (
<div class="flex flex-1 items-center gap-1 overflow-y-auto">
<For each={legendList()}>
{(legend) => {
const initialColors = {} as any;
const darkenColors = {} as any;
Object.entries(legend.series.options()).forEach(([k, v]) => {
if (k.toLowerCase().includes("color") && v) {
initialColors[k] = v;
darkenColors[k] = `${v}${transparency}`;
} else if (k === "lastValueVisible" && v) {
initialColors[k] = v;
darkenColors[k] = !v;
}
});
createEffect(() => {
if (hovering()) {
if (hovering()?.title !== legend.title) {
legend.series.applyOptions(darkenColors);
}
} else {
legend.series.applyOptions(initialColors);
}
});
let previousClickValueOf: number = 0;
return (
<Show when={!legend.disabled()}>
<button
onMouseEnter={() => {
hovering.set(legend);
}}
onMouseLeave={() => hovering.set(undefined)}
onClick={() => {
const currentClickValueOf = new Date().valueOf();
if (currentClickValueOf - previousClickValueOf > 300) {
legend.visible.set((visible) => !visible);
} else {
legendList().forEach((_legend) => {
if (_legend.title != legend.title) {
_legend.visible.set(toggle);
}
});
legend.visible.set(true);
toggle = !toggle;
}
previousClickValueOf = currentClickValueOf;
}}
class="flex flex-none items-center space-x-1.5 rounded-full py-1.5 pl-2 pr-2.5 hover:bg-orange-200/20 active:scale-[0.975]"
>
<span
class="flex size-4 flex-col overflow-hidden rounded-full"
style={{
opacity: legend.visible() ? 1 : 0.5,
}}
>
<For
each={
Array.isArray(legend.color())
? (legend.color() as string[])
: [legend.color() as string]
}
>
{(color) => (
<span
class="w-full flex-1"
style={{
"background-color": color,
}}
/>
)}
</For>
</span>
<span
class="text-white decoration-white decoration-wavy decoration-[1.5px]"
style={{
"text-decoration-line": !legend.visible()
? "line-through"
: undefined,
"--tw-text-opacity": legend.visible() ? 1 : 0.5,
}}
>
{legend.title}
</span>
<Show when={legend.url}>
{(url) => (
<a
class="-my-0.5 !-mr-1 inline-flex size-6 flex-col overflow-hidden rounded-full border border-orange-200/5 bg-orange-200 bg-opacity-5 p-1 pl-0.5 hover:bg-opacity-30"
style={{
opacity: legend.visible() ? 1 : 0.5,
}}
onClick={(event) => {
event.stopPropagation();
// event.preventDefault();
}}
href={url()}
target={
url()?.startsWith("/") || url()?.startsWith("http")
? "_blank"
: undefined
}
>
<IconTablerExternalLink />
</a>
)}
</Show>
</button>
</Show>
);
}}
</For>
</div>
);
}
@@ -1,67 +0,0 @@
import { chartState } from "/src/scripts/lightweightCharts/chart/state";
import { GENESIS_DAY } from "/src/scripts/lightweightCharts/chart/whitespace";
import { ONE_DAY_IN_MS } from "/src/scripts/utils/time";
import { Box } from "../../box";
export function TimeScale() {
return (
<Box dark padded overflowY>
<Button onClick={() => setTimeScale()}>All Time</Button>
<Button onClick={() => setTimeScale(7)}>1 Week</Button>
<Button onClick={() => setTimeScale(30)}>1 Month</Button>
<Button onClick={() => setTimeScale(30 * 6)}>6 Months</Button>
<Button
onClick={() =>
setTimeScale(
Math.ceil(
(new Date().valueOf() -
new Date(`${new Date().getUTCFullYear()}-01-01`).valueOf()) /
ONE_DAY_IN_MS,
),
)
}
>
Year To Date
</Button>
<Button onClick={() => setTimeScale(365)}>1 Year</Button>
<Button onClick={() => setTimeScale(2 * 365)}>2 Years</Button>
<Button onClick={() => setTimeScale(4 * 365)}>4 Years</Button>
<Button onClick={() => setTimeScale(8 * 365)}>8 Years</Button>
</Box>
);
}
function Button(props: ParentProps & { onClick: VoidFunction }) {
return (
<button
class="min-w-20 flex-shrink-0 flex-grow whitespace-nowrap rounded-lg px-2 py-1.5 hover:bg-white/20 active:scale-95"
onClick={props.onClick}
>
{props.children}
</button>
);
}
function setTimeScale(days?: number) {
const to = new Date();
if (days) {
const from = new Date();
from.setDate(from.getUTCDate() - days);
chartState.chart?.timeScale().setVisibleRange({
from: (from.getTime() / 1000) as Time,
to: (to.getTime() / 1000) as Time,
});
} else {
// chartState.chart?.timeScale().fitContent();
chartState.chart?.timeScale().setVisibleRange({
from: (new Date(
// datasets.candlesticks.values()?.[0]?.date || "",
GENESIS_DAY,
).getTime() / 1000) as Time,
to: (to.getTime() / 1000) as Time,
});
}
}
@@ -1,12 +0,0 @@
export function Title({ presets }: { presets: Presets }) {
return (
<div class="flex flex-1 items-center overflow-y-auto pb-1.5 text-orange-100/50">
<div class="flex-1 -space-y-1 whitespace-nowrap px-1 md:mt-0.5 md:-space-y-1.5">
<h3 class="text-xs">{`/ ${[...presets.selected().path.map(({ name }) => name), presets.selected().name].join(" / ")}`}</h3>
<h1 class="text-lg font-bold text-white md:text-xl">
{presets.selected().title}
</h1>
</div>
</div>
);
}
@@ -1,72 +0,0 @@
import { classPropToString } from "/src/solid/classes";
import { createRWS } from "/src/solid/rws";
import { Box } from "../box";
import { Actions } from "./components/actions";
import { Legend } from "./components/legend";
import { TimeScale } from "./components/timeScale";
import { Title } from "./components/title";
export function ChartFrame({
presets,
datasets,
activeResources,
hide,
qrcode,
standalone,
fullscreen,
}: {
presets: Presets;
hide?: Accessor<boolean>;
qrcode: RWS<string>;
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
datasets: Datasets;
fullscreen?: RWS<boolean>;
standalone: boolean;
}) {
const legend = createRWS<PresetLegend>([]);
const Chart = lazy(() =>
import("./components/chart").then((d) => ({
default: d.Chart,
})),
);
return (
<div
class={classPropToString([
standalone &&
"rounded-2xl border border-orange-200/15 bg-gradient-to-b from-orange-100/5 to-black/10 to-80%",
"flex size-full min-h-0 flex-1 flex-col overflow-hidden",
])}
style={{
display: (hide ? !hide() : true) ? undefined : "none",
}}
>
<Box flex={false} dark>
<Title presets={presets} />
<div class="-mx-2 border-t border-orange-200/15" />
<div class="flex pt-1.5">
<Legend legend={legend} />
<div class="-my-1.5 border-l border-orange-200/15 pr-1.5" />
<Actions presets={presets} qrcode={qrcode} fullscreen={fullscreen} />
</div>
</Box>
<div class="-mt-2 min-h-0 flex-1">
<Chart
activeResources={activeResources}
datasets={datasets}
legendSetter={legend.set}
presets={presets}
/>
</div>
<TimeScale />
</div>
);
}
-25
View File
@@ -1,25 +0,0 @@
export function Counter({
count,
name,
setRef,
}: {
count: () => number;
name: string;
setRef?: Setter<HTMLDivElement | undefined>;
}) {
return (
<div
ref={setRef}
class="text-orange-100/75"
style={{
"border-style": count() ? "dashed" : "none",
}}
>
Counted{" "}
<span class="font-medium text-orange-400/75">
{count().toLocaleString("en-us")}
</span>{" "}
{name}
</div>
);
}
@@ -1,48 +0,0 @@
import { Header } from "./header";
import { Line } from "./line";
import { Number } from "./number";
export function FavoritesFrame({
presets,
selectedFrame,
}: {
presets: Presets;
selectedFrame: Accessor<FrameName>;
}) {
return (
<div
class="flex-1 overflow-y-auto"
hidden={selectedFrame() !== "Favorites"}
>
<div class="flex max-h-full min-h-0 flex-1 flex-col gap-4 p-4">
<Header title="Favorites">
<Number number={() => presets.favorites().length} /> presets marked as
favorites.
</Header>
<div class="-mx-4 border-t border-orange-200/10" />
<div
class="space-y-0.5 py-1"
style={{
display: !presets.favorites().length ? "none" : undefined,
}}
>
<For each={presets.favorites()}>
{(preset) => (
<Line
id={`favorite-${preset.id}`}
name={preset.title}
onClick={() => presets.select(preset)}
active={() => presets.selected() === preset}
header={`/ ${[...preset.path.map(({ name }) => name), preset.name].join(" / ")}`}
/>
)}
</For>
</div>
<div class="h-[25dvh] flex-none" />
</div>
</div>
);
}
-8
View File
@@ -1,8 +0,0 @@
export function Header({ title, children }: { title: string } & ParentProps) {
return (
<div>
<h3 class="text-lg font-bold md:text-xl">{title}</h3>
<p class="text-orange-100/75">{children}</p>
</div>
);
}

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