Artur 82955be4cb Campaign Site V2 (#81)
* Apply OpenSats UI enhancements

* Add register modal and some UI fixes

* Add login modal

* Add reset password button

* Use @t3-oss/env-nextjs for env variables

* Email verification without keycloak UI

* Password reset without keycloak UI

* Add "My donations" page with one-time stripe donations list

* Display crypto donations in "My donations" page

* Donation form fixes and improvements

* Display recurring annual fiat donations

* Include keycloak realm export file and remove hardcoded client values

* fix: correctly handle btcpay webhooks and fix donationList query

* feat: add membership modal and implement membership payment using btcpay

* feat: add procedure for membership purchases with stripe and use db as single source of truth for donations

* feat: use webhooks to update stripe donation/membership status

* feat: memberships list page and fixes

* feat: db schema changes and webhook fixes

* feat: re-add "donate" and add "get annual membership" buttons to project page

* feat: open register modal when clicking membership button while logged out

* feat: replace "Get Membership" button with "My Memberships" button when user already has a membership for that project

* feat: multiple funds support

* deps: bump axios

* feat: add different color schemes for each fund and some fixes

* feat: add home page

* feat: add missing titles and responsiveness improvements

* chore: add prod workflow file and compose file

* chore(deploy workflow): set environment name

* chore(Dockerfile): add necessary lines for prisma

* chore: make it skip env validation on build

* fix: prevent donation amounts from being fetched from db during build

* chore(nginx.conf): remove copy-paste junk

* chore(docker compose): correctly set APP_URL env

* feat: replace Sendgrid with SES

* deps: audit fix

* chore(deploy.yml): remove unecessary env

* fix: correctly manage client and server env

* fix(trpc.submitApplication): get recipient emails from server side env

* fix(Dockerfile): define NEXT_PUBLIC_ env on build

* chore(trpc): make it log any errors

* chore(trpc): improve displaying of errors

* chore(trpc): improve displaying of errors

* fix: buggy link buttons

* feat: use single btcpay store

* feat: show form 8283 info in donation form and handle tax deductible donations

* feat: have only one privacy and terms page for the entire site

* feat: support many social links

* feat: add funding required endpoint (wip)

* feat: get rates using btcpay api and small refactor

* deps: audit fix

* fix: correctly handle payment methods on InvoiceSettled event

* fix: make index on Donation.btcPayInvoiceId

* feat(funding-required): improve asset parameter response

* feat(funding-required): add project_status param

* feat(funding-required): add fund param

* feat(funding-required): implement caching

* fix(funding-required): minor fixes

* feat(funding-required): add remaining_amount_<currency> fields and fixes

* chore: include all services in docker-compose.dev.yml and update .env.example

* feat: move terms and privacy links to footer

* fix: address font not always loading bug

* feat: use fund logos as header image

* feat: donation confirmation email

* fix: use correct stripe client for each fund on webhooks

* feat: add account settings page with change password form

* feat: add email change form to settings page

* fix: address wrong btcpay invoice url redirect

* chore: email change request debug

* fix(api): better handle user attributes

* feat: ui improvements

* feat: add btcpay invoice item description

* chore(nginx): api rate limit

* feat: remove typing component from fund landing pages

* feat: implement refresh token rotation using keycloak

* refactor: have gross and net amounts for donations

* feat: invalidate user sessions on password/email change

* fix: make "Create an account" button work on donate/membership modals

* refactor: project props

* fix(utils.md): correctly load md project attributes

* chore(prisma): make composite unique constraint for fundSlug and projectSlug on ProjectAddresses

* chore: mark example project as not funded

* fix(utils.md): serialization error

* chore(funding-required): btcpay invoice payment methods debug

* fix(funding-required): get bitcoin address from correct payment method

* fix(funding-required): correctly handle project_status ANY filter

* fix(btcpay webhook handler): correctly handle payment methods on InvoicePaymentSettled

* chore(docker-compose.yml): expose nginx port 80

* fix(funding-required): correctly concat project url

* feat: ui improvements for smaller screens

* fix(btcpay webhook handler): correctly get payment method amount on InvoiceSettled

* fix(btcpay webhook handler): respond with 200 immediately if there is no metadata

* chore(funding-required): debugging

* chore(funding-required): debugging

* chore(funding-required): debugging

* fix(Dockerfile): define BUILD_MODE as arg instead of env to make it blank at runtime

* fix: correctly pass current and goal values to project card progress

* fix(funding-required): set high monitoring time for static address invoice

* fix: correctly handle refresh token expiration on the ui

* feat: ui improvements

* chore: update README

* chore: update README

* Initial site text

* fix: colors

* chore: mention funds accordingly in texts

* chore: update realm-export.json

* chore: rename docker compose files

* Update emails

* Form updates

* Remove unused pages and page improvements

* feat: allow editing navbar links for each fund

* Cleanup and Firo projects

* chore(deploy.yml): change deploy branch to master

* fix(auth): use fetch instead of axios when fetching refresh token due to edge runtime compatibility

* fix: keep empty project folders

* Fix code scanning alert no. 20: DOM text reinterpreted as HTML

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* chore: sanitize md file paths

* Text and link updates

---------

Co-authored-by: Artur N <arturnunespe@gmail.com>
Co-authored-by: Justin Ehrenhofer <12520755+SamsungGalaxyPlayer@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2022-11-11 16:52:31 -06:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2022-10-13 13:58:49 +00:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2022-10-13 14:06:29 +00:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2022-03-18 19:40:50 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00
2024-10-17 10:29:40 -05:00

MAGIC Grants Campaign Site

Development

Requirements

  • Docker
  • Docker Compose
  • NodeJS >=20

Running containers

First, install the application's dependencies and then run the containers:

$ npm i
$ docker-compse up -d

The app will be available at http://localhost:3000.

Configuration

Create a .env file as a copy of .env.example and set the values for the empty variables.

Setting up Keycloak

  1. Open up http://localhost:8080 in your browser, then login using admin for both username and password;

  2. Open the dropdown menu on the top left corner of the screen (where it says Keycloak) and click Create realm;

  3. Upload the realm-export.json file from this repo, name the realm magic and click Create;

  4. Once the realm is created, go to Clients -> Credentials, and under Client Secret, click Regenerate. Copy the secret and add it to the KEYCLOAK_CLIENT_SECRET environment variable in your .env file.

Setting up BTCPayServer

  1. Open up http://localhost:49392 in your browser and create an account;

  2. Once logged in, open the XMR Wallet page and upload a view-only wallet file, you can get one from Feather Wallet;

  3. In the Webhooks tab, create a new webhook by setting the Payload URL to http://campaign-site:3000/api/btcpay/webhook, copy the secret and add it to the BTCPAY_WEBHOOK_SECRET environment variable in your .env file, and finally click Add webhook.

  4. Create a new API key at Account -> Manage Account -> API Keys, you'll need the following permissions: View invoices, Create an invoice and View your stores. Then copy the API key and add it to the BTCPAY_API_KEY environment variable in your .env file.

Setting up Stripe

  1. Open up the Stripe Dashboard in your browser;

  2. Create a new account in test mode;

  3. Go to Developers -> API keys, and get a secret key, add it to the STRIPE_MONERO_SECRET_KEY environment variable in your .env file;

  4. Go to Developers -> Webhooks, and add a new webhook endpoint. Add <Your app public address>/api/stripe/monero-webhook to the URL field replacing <Your app public address> with your app's public address, then add the secret to the STRIPE_MONERO_WEBHOOK_SECRET environment variable in your .env file. To expose the app to the internet so Stripe can reach the webhook endpoint, you can use tunneling services like Visual Studio Code's built-in port-forwarding feature or Ngrok.

This makes you able to test Stripe donations in the Monero fund, which should be enough for development. You can add random values to the other Stripe enviroment variables to bypass validation.

You are now all set up to start developing!

Funding required endpoint

Endpoint: GET /api/funding-required

Request query parameters

Parameter Required Default Accepted values Description
fund No - monero firo privacyguides general Filters projects by fund.
asset No - BTC XMR USD Only return project amounts and address for a specific asset. Specifying this parameter changes the response JSON schema as shown below.
project_status No NOT_FUNDED NOT_FUNDED FUNDED ANY Filters projects by status.

Response body (asset parameter not specified)

[
    {
        title: string
        fund: 'monero' | 'firo' | 'privacyguides' | 'general'
        date: string // YYYY-MM-DD
        author: string
        url: string
        is_funded: boolean
        raised_amount_percent: number
        contributions: number
        target_amount_btc: number
        target_amount_xmr: number
        target_amount_usd: number
        remaining_amount_btc: number
        remaining_amount_xmr: number
        remaining_amount_usd: number
        address_btc: string | null
        address_xmr: string | null
    }
]

Response body (asset parameter specified)

[
    {
        title: string
        fund: 'monero' | 'firo' | 'privacyguides' | 'general'
        date: string // YYYY-MM-DD
        author: string
        url: string
        is_funded: boolean
        raised_amount_percent: number
        contributions: number
        asset: 'BTC' | 'XMR' | 'USD'
        target_amount: number
        remaining_amount: number
        address: string | null
    }
]

Contributing

Pull requests welcome! Thanks for supporting MAGIC Grants.

License

MIT

Description
No description provided
Readme MIT 12 MiB
Languages
TypeScript 97.5%
JavaScript 1.6%
CSS 0.5%
Dockerfile 0.4%