├── .dockerignore ├── static ├── images │ ├── favicon.ico │ └── default_listing.png └── css │ ├── fonts │ ├── 1Ptug8zYS_SKggPNyC0ITw.woff2 │ ├── 1Ptug8zYS_SKggPNyCAIT5lu.woff2 │ ├── 1Ptug8zYS_SKggPNyCIIT5lu.woff2 │ ├── 1Ptug8zYS_SKggPNyCMIT5lu.woff2 │ └── 1Ptug8zYS_SKggPNyCkIT5lu.woff2 │ ├── style.css │ ├── normalize.min.css │ ├── fonts.css │ └── skeleton.min.css ├── templates ├── logout.html.tera ├── deleted.html.tera ├── users.html.tera ├── index.html.tera ├── activeusers.html.tera ├── disabledusers.html.tera ├── mypaidorders.html.tera ├── myunpaidorders.html.tera ├── myactivelistings.html.tera ├── mypendinglistings.html.tera ├── myrejectedlistings.html.tera ├── mydeactivatedlistings.html.tera ├── myunsubmittedlistings.html.tera ├── reviewpendinglistings.html.tera ├── search.html.tera ├── deactivatedlistingsindex.html.tera ├── listingsindex.html.tera ├── myprocessingorders.html.tera ├── unreadmessagepage.html.tera ├── marketliabilities.html.tera ├── myaccountbalance.html.tera ├── sellerhistory.html.tera ├── search_form.html.tera ├── login.html.tera ├── signup.html.tera ├── withdrawal.html.tera ├── updatepgpinfo.html.tera ├── updateuserpgpinfo.html.tera ├── updatemarketname.html.tera ├── updatefeerate.html.tera ├── withdraw.html.tera ├── updateuserbondprice.html.tera ├── updatemaxallowedusers.html.tera ├── userprofile.html.tera ├── about.html.tera ├── deletelisting.html.tera ├── topsellers.html.tera ├── newlisting.html.tera ├── usertablepage.html.tera ├── deactivateaccount.html.tera ├── admin.html.tera ├── updatesqueaknodeinfo.html.tera ├── updateusersqueaknodeinfo.html.tera ├── accountbalancechangepage.html.tera ├── listingtablepage.html.tera ├── ordercardpage.html.tera ├── user.html.tera ├── searchlistingtablepage.html.tera ├── account.html.tera ├── accountactivation.html.tera ├── updatelistingimages.html.tera ├── prepareorder.html.tera ├── updateshippingoptions.html.tera ├── base.html.tera └── listing.html.tera ├── Rocket.toml ├── src ├── db.rs ├── util.rs ├── activate_account.rs ├── lightning.rs ├── config.rs ├── image_util.rs ├── user_account.rs ├── base.rs ├── admin.rs ├── main.rs ├── active_users.rs ├── disabled_users.rs ├── deactivated_listings.rs ├── top_sellers.rs ├── my_paid_orders.rs ├── review_pending_listings.rs ├── withdrawal.rs ├── my_unpaid_orders.rs ├── account.rs ├── my_processing_orders.rs ├── user_profile.rs ├── listings.rs ├── my_deactivated_listings.rs ├── order_expiry.rs ├── my_active_listings.rs ├── my_pending_listings.rs ├── my_rejected_listings.rs ├── my_unsubmitted_listings.rs ├── search.rs ├── market_liabilities.rs ├── my_account_balance.rs ├── user_account_expiry.rs ├── tests.rs ├── about.rs ├── update_pgp_info.rs ├── seller_history.rs ├── update_max_allowed_users.rs ├── update_market_name.rs ├── update_user_bond_price.rs ├── update_user_pgp_info.rs ├── update_fee_rate.rs ├── payment_processor.rs ├── update_squeaknode_info.rs ├── delete_listing.rs ├── update_user_squeaknode_info.rs ├── account_activation.rs ├── new_listing.rs └── user.rs ├── Makefile ├── .github └── workflows │ ├── audit.yaml │ ├── ci.yaml │ └── docker.yaml ├── entrypoint.sh ├── Dockerfile ├── .gitignore ├── LICENSE ├── Cargo.toml ├── README.md └── db └── migrations └── 20220729073857_initial_migration.sql /.dockerignore: -------------------------------------------------------------------------------- 1 | /.dockerignore 2 | /.git 3 | /.gitignore 4 | /Dockerfile 5 | /target 6 | -------------------------------------------------------------------------------- /static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzernik/squeakroad/HEAD/static/images/favicon.ico -------------------------------------------------------------------------------- /static/images/default_listing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzernik/squeakroad/HEAD/static/images/default_listing.png -------------------------------------------------------------------------------- /templates/logout.html.tera: -------------------------------------------------------------------------------- 1 | {% extends "base" %} 2 | {% block body %} 3 | You're logged out 4 | 5 | {% endblock body %} 6 | -------------------------------------------------------------------------------- /Rocket.toml: -------------------------------------------------------------------------------- 1 | [default.databases.squeakroad] 2 | url = "db.sqlite" 3 | 4 | [default.limits] 5 | file = "10 MiB" 6 | data-form="10 MiB" -------------------------------------------------------------------------------- /static/css/fonts/1Ptug8zYS_SKggPNyC0ITw.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzernik/squeakroad/HEAD/static/css/fonts/1Ptug8zYS_SKggPNyC0ITw.woff2 -------------------------------------------------------------------------------- /static/css/fonts/1Ptug8zYS_SKggPNyCAIT5lu.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzernik/squeakroad/HEAD/static/css/fonts/1Ptug8zYS_SKggPNyCAIT5lu.woff2 -------------------------------------------------------------------------------- /static/css/fonts/1Ptug8zYS_SKggPNyCIIT5lu.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzernik/squeakroad/HEAD/static/css/fonts/1Ptug8zYS_SKggPNyCIIT5lu.woff2 -------------------------------------------------------------------------------- /static/css/fonts/1Ptug8zYS_SKggPNyCMIT5lu.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzernik/squeakroad/HEAD/static/css/fonts/1Ptug8zYS_SKggPNyCMIT5lu.woff2 -------------------------------------------------------------------------------- /static/css/fonts/1Ptug8zYS_SKggPNyCkIT5lu.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yzernik/squeakroad/HEAD/static/css/fonts/1Ptug8zYS_SKggPNyCkIT5lu.woff2 -------------------------------------------------------------------------------- /src/db.rs: -------------------------------------------------------------------------------- 1 | use rocket_db_pools::{sqlx, Database}; 2 | 3 | #[derive(Database)] 4 | #[database("squeakroad")] 5 | pub struct Db(pub sqlx::SqlitePool); 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: test 2 | 3 | clean: 4 | cargo clean 5 | 6 | test: 7 | cargo test 8 | 9 | lint: 10 | cargo clippy 11 | 12 | .PHONY: all clean test lint 13 | -------------------------------------------------------------------------------- /templates/deleted.html.tera: -------------------------------------------------------------------------------- 1 | {% extends "base" %} 2 | {% block body %} 3 | You're account has been deleted. You can verify here 4 | {% endblock body %} -------------------------------------------------------------------------------- /templates/users.html.tera: -------------------------------------------------------------------------------- 1 | {% extends "base" %} 2 | {% block body %} 3 |
Orders you have received that you have not yet shipped
13 | 14 |Message for order ID: {{ order_message_card.order_public_id }}
7 | 8 |Total Market Liabilities: {{ total_market_liabilities_sat }} sats
16 | 17 | {% include "accountbalancechangepage" %} 18 | 19 |Account Balance: {{ account_balance_sat }} sats
16 | 17 | 18 | {% include "accountbalancechangepage" %} 19 | 20 |User: {{ visited_user.username }}
16 |Total Amount Sold: {{ amount_sold_sat }} sats
17 |Weighted Average Rating: {{ weighted_average_rating | round(method="ceil", precision=2) }}
18 | 19 | {% include "ordercardpage" %} 20 | 21 |Withdrawal id: {{ withdrawal.public_id }}
20 |User: {% if maybe_withdrawal_user %}{{ maybe_withdrawal_user.username }}{% else %}Not found{% endif %}
21 |Amount: {{ withdrawal.amount_sat }} sats
22 |Withdrawal time: {{ (withdrawal.created_time_ms / 1000) | int | date(format="%Y-%m-%d %H:%M") }}
23 |Invoice hash: {{ withdrawal.invoice_hash }}
24 | 25 |PGP Key: {% if admin_settings.pgp_key %}
{{ admin_settings.pgp_key }}{% else %}Not set{% endif %}
14 |
15 |
30 | PGP Key: {% if user_settings.pgp_key %}
{{ user_settings.pgp_key }}{% else %}Not set{% endif %}
14 |
15 |
30 | Market Name: {{ admin_settings.market_name }}
14 | 15 | 30 |Fee Rate: {{ admin_settings.fee_rate_basis_points / 100 }}%
14 | 15 | 30 |Account Balance: {{ account_balance_sat }} sats
18 | 19 | 20 | 30 | 31 |Bond Price: {{ admin_settings.user_bond_price_sat }} sats
14 | 15 | 30 |Max allowed users: {{ admin_settings.max_allowed_users }}
14 | 15 | 30 |User: {{ visited_user.username }}
14 | 15 |PGP Key: {% if visited_user_settings.pgp_key %}
{{ visited_user_settings.pgp_key }}{% else %}Not set{% endif %}
16 |
17 | Squeaknode Pubkey: {% if visited_user_settings.squeaknode_pubkey %}{{ visited_user_settings.squeaknode_pubkey }}{% else %}Not set{% endif %}
20 |Squeaknode Address: {% if visited_user_settings.squeaknode_address %}{{ visited_user_settings.squeaknode_address }}{% else %}Not set{% endif %}
21 |Market Name: {{ admin_settings.market_name }}
7 |Market Fee Rate: {{ admin_settings.fee_rate_basis_points / 100 }}% of each sale
8 |User Bond Price: {{ admin_settings.user_bond_price_sat }} sats
9 |Lightning Node: {{ lightning_node_pubkey }}
10 | 11 |PGP Key: {% if admin_settings.pgp_key %}
{{ admin_settings.pgp_key }}{% else %}Not set{% endif %}
12 |
13 | Squeaknode Pubkey: {% if admin_settings.squeaknode_pubkey %}{{ admin_settings.squeaknode_pubkey }}{% else %}Not set{% endif %}
15 |Squeaknode Address: {% if admin_settings.squeaknode_address %}{{ admin_settings.squeaknode_address }}{% else %}Not set{% endif %}
16 | 17 | {% endblock body %} 18 | -------------------------------------------------------------------------------- /templates/deletelisting.html.tera: -------------------------------------------------------------------------------- 1 | {% extends "base" %} 2 | {% block body %} 3 | 4 |Are you sure you want to delete this listing?
22 | 23 | 32 | 33 || User | 19 |Total Amount Sold | 20 |Rating | 21 |
|---|---|---|
| {{ seller_info.username }} | 28 |{{ seller_info.total_amount_sold_sat }} sats | 29 |{{ seller_info.weighted_average_rating | round(method="ceil", precision=2) }} (See rating) | 30 |
Market will collect a {{ admin_settings.fee_rate_basis_points / 100 }}% fee from each sale
12 | 31 || Username | 5 |Creation Time | 6 |User Bond Amount | 7 |Status | 8 |
|---|---|---|---|
| 15 | 16 | {{ card.user.username }} 17 | 18 | | 19 |20 | {{ (card.user_account.created_time_ms / 1000) | int | date(format="%Y-%m-%d %H:%M") }} 21 | | 22 |23 | {{ card.user_account.amount_owed_sat }} sats 24 | | 25 |26 | {% if card.user_account.disabled %} 27 | Disabled by admin 28 | {% elif card.user_account.paid %} 29 | Paid 30 | {% else %} 31 | Not paid 32 | {% endif %} 33 | | 34 |
This action is permanent. Once you deactivate your account, you will not be able to access your account anymore.
17 |Be sure to withdraw all funds from your account before deactivating.
18 |When you are ready to deactive, you can submit a payment request for the amount of your account activation bond.
19 | 20 | 21 | 22 |Account Activation Deposit: {{ user_account.amount_owed_sat }} sats
23 | 24 | 34 | 35 |Pubkey: {{ admin_settings.squeaknode_pubkey }}
15 | {% endif %} 16 | {% if admin_settings.squeaknode_address %} 17 |Address: {{ admin_settings.squeaknode_address }}
18 | {% endif %} 19 | 20 | 38 |Squeaknode Pubkey: {% if user_settings.squeaknode_pubkey %}{{ user_settings.squeaknode_pubkey }}{% else %}Not set{% endif %}
14 |Squeaknode Address: {% if user_settings.squeaknode_address %}{{ user_settings.squeaknode_address }}{% else %}Not set{% endif %}
15 | 16 | 34 || Event time | 5 |Amount change | 6 |Event type | 7 |Event id | 8 |
|---|---|---|---|
| {{ (account_balance_change.event_time_ms / 1000) | int | date(format="%Y-%m-%d %H:%M") }} | 15 |{{ account_balance_change.amount_change_sat }} sats | 16 |{{ account_balance_change.event_type }} | 17 |{{ account_balance_change.event_id }} | 30 |
| 5 | | 6 | |
|---|---|
13 |
14 | {% if card.image %}
15 |
18 | {% endif %}
19 |
20 | |
21 |
22 |
23 | {{ card.listing.title }}24 | 25 | 26 | {{ card.listing.price_sat }} sats 27 | 28 |29 | 30 | {{ card.user.username }} 31 | 32 | |
33 |
| Payment Time | 5 |Status | 6 |Order | 7 |Listing | 8 |Sale Amount | 9 |Rating | 10 |
|---|---|---|---|---|---|
| {% if order_card.order.paid %}{{ (order_card.order.payment_time_ms / 1000) | int | date(format="%Y-%m-%d %H:%M") }}{% else %}None{% endif %} | 17 |18 | {% if not order_card.order.paid %} 19 | Not paid 20 | {% else %} 21 | {% if order_card.order.shipped %}Shipped{% elif order_card.order.canceled_by_seller%}Canceled by seller{% elif order_card.order.canceled_by_buyer %}Canceled by buyer{% else %}Processing (waiting for seller to ship){% endif %} 22 | {% endif %} 23 | | 24 |{{ order_card.order.public_id }} | 25 |{% if order_card.listing %}{{ order_card.listing.title }}{% else %}Not found{% endif %} | 26 |{{ order_card.order.amount_owed_sat }} sats | 27 |{% if order_card.order.reviewed %}{{ order_card.order.review_rating }}{% else %}Unrated{% endif %} | 28 |
User rating: {{ weighted_average_rating | round(method="ceil", precision=2) }} (See rating)
20 |User account status: {% if visited_user_account.disabled %} 21 | Disabled by admin 22 | {% elif visited_user_account.paid %} 23 | Paid 24 | {% else %} 25 | Not paid 26 | {% endif %}
27 | {% if admin_user %} 28 | {% if not visited_user_account.disabled %} 29 | 33 | {% else %} 34 | 38 | {% endif %} 39 | {% endif %} 40 | 41 | 42 | 43 || 5 | | 6 | |
|---|---|
13 |
14 | {% if card.image %}
15 |
18 | {% endif %}
19 |
20 | |
21 |
22 |
23 | {{ card.listing.title }}24 | 25 | 26 | {{ card.listing.price_sat }} sats 27 | 28 |29 | 30 | {{ card.user.username }} 31 | 32 | |
33 |
User: {% if maybe_account_user %}{{ maybe_account_user.email }}{% else %}Not found{% endif %}
17 |Status: 18 | {% if user_account.disabled %} 19 | Disabled by admin 20 | {% elif user_account.paid %} 21 | Paid 22 | {% else %} 23 | Not paid 24 | {% endif %}
25 |Account creation time: {{ (user_account.created_time_ms / 1000) | int | date(format="%Y-%m-%d %H:%M") }}
26 | 27 |Payment amount: {{ user_account.amount_owed_sat }} sats
28 | 29 | {% if user_account.disabled %} 30 | Please contact the admin to find out how to get your account re-enabled. 31 | {% elif user_account.paid %} 32 |Payment time: {{ (user_account.payment_time_ms / 1000) | int | date(format="%Y-%m-%d %H:%M") }}
33 | {% if user.id == user_account.user_id %} 34 | 35 | 36 | {% endif %} 37 | {% else %} 38 |A user bond is required to activate your account.
39 |You can withdraw the bond at any time in the future when you deactivate your account (as long as you don't misbehave).
40 |Payment request:
41 |
42 |
43 |
44 | {{ user_account.invoice_payment_request }}
45 |
46 |
47 | Open a channel to the market: {{ lightning_node_pubkey }}
48 | {% endif %} 49 | 50 |Listing: {{ listing_display.listing.title }} ({{ listing_display.listing.price_sat }} sats)
24 |Quantity: {{ quantity }}
25 |Shipping Option: {{ selected_shipping_option.title }} ({{ selected_shipping_option.price_sat }} sats)
26 |Shipping option description: {{ selected_shipping_option.description }}
27 | 28 |Total Price: {{ quantity }} x ({{ listing_display.listing.price_sat }} sats + {{ selected_shipping_option.price_sat }} sats) = {{ quantity * (selected_shipping_option.price_sat + listing_display.listing.price_sat) }} sats
29 | 30 |Seller PGP Key: {% if seller_user_settings.pgp_key %}
{{ seller_user_settings.pgp_key }}{% else %}Not set{% endif %}
31 |
32 |
42 |
43 |