# SoulWall

SoulWall is a standalone charity access gateway and public donation ledger.

## Deployment Note

Do not deploy this folder with Cloudflare's browser drag-and-drop uploader. That uploader treats the project as static files and shows `Pages functions are not supported` because SoulWall uses backend routes in `functions/`.

Use one of these instead:

```bash
npm install
npm run dev
npm run deploy
```

Or deploy through Cloudflare Pages with Git integration, using this repository root as the project root and no build command. The static output directory is `.`.

## What Ships Here

- `index.html`, `site.css`, `app.js` - standalone public gateway.
- `widget/soulwall-widget.js` - embeddable client widget for third-party projects.
- `assets/soulwall-logo.png` - SoulWall brand asset.
- `functions/api/soulwall/` - SoulWall API endpoints and shared helpers.
- `functions/api/soulwall/telemetry.js` - donation confirmation ping receiver.
- `functions/api/soulwall/ledger.js` - public aggregate ledger endpoint.
- `functions/api/v1/soulwall-verify.js` - provider verification endpoint.
- `functions/webhook/every-donation.js` - donation webhook handler.
- `docs/soulwall-*.sql` - Supabase schema and provider migrations.
- `.dev.vars.example` - sanitized local environment template.
- `wrangler.toml` - Cloudflare Pages deployment config.

## Required Setup

1. Copy `.dev.vars.example` to `.dev.vars`.
2. Fill `SOULWALL_SESSION_SECRET`, `SUPABASE_URL`, and the Supabase key values.
3. Run the SQL migrations in `docs/`, including `docs/soulwall-ledger-migration.sql`.
4. Run `npm run dev` for local Cloudflare Pages Functions.
5. Deploy with `npm run deploy`.
6. In Cloudflare Pages, attach the custom domain `soulwall.org`.

## Public API

### `GET /api/soulwall/session`

Returns the current browser session state.

### `GET /api/soulwall/charities`

Returns configured donation projects for the active charity rail.

### `POST /api/soulwall/intent`

Creates a donation intent for authenticated users.

### `POST /api/soulwall/giveth-verify`

Verifies a Polygon transaction hash against a selected Giveth project. If `projectSlug` is omitted, SoulWall scans the configured charity cards and infers the project when possible.

Payload:

```json
{
  "txHash": "0x...",
  "projectSlug": "optional-giveth-project-slug",
  "partnerDonationId": "optional-intent-id"
}
```

### `POST /api/soulwall/telemetry`

Receives a confirmed donation ping from the SoulWall widget or a partner integration and writes it to `public.soulwall_ledger`.

Payload:

```json
{
  "clientId": "example-app",
  "provider": "giveth",
  "projectSlug": "giveth-project-slug",
  "projectName": "Project Name",
  "txHash": "0x...",
  "amountUsd": 1.25,
  "amountNative": 2.3,
  "currency": "USD",
  "network": "polygon",
  "status": "confirmed"
}
```

### `GET /api/soulwall/ledger`

Returns public network totals and recent confirmed donation events.

## Widget Install

Add this to a client project:

```html
<script src="https://soulwall.org/widget/soulwall-widget.js"
  data-soulwall-client="your-project"
  data-soulwall-project="giveth-project-slug"
  data-soulwall-provider="giveth"></script>
```

After a provider confirms a donation, report it:

```js
await SoulWall.pingDonation({
  txHash: '0x...',
  amountUsd: 1.25,
  projectName: 'Project Name'
});
```

For Giveth, the widget can verify and then ping the ledger:

```js
await SoulWall.verifyGivethDonation({
  txHash: '0x...',
  projectSlug: 'giveth-project-slug'
});
```

## Ledger Policy

The public ledger is append-oriented and deduplicated by `event_id`. When a transaction hash is present, the widget uses it as the event id. Supabase service-role writes happen only from Cloudflare Functions. Public users can read the ledger but cannot write directly to Supabase.

## Public Source Mirrors

The live site exposes a sanitized source package at `/source/` and `SOURCE.md`. This includes the widget, public API function mirrors, and ledger SQL migration. Runtime secrets are deliberately excluded.

## Deliberately Not Included

- `.dev.vars` - local secrets and private config.
- `.wrangler/` - local Cloudflare cache/state.
- Market app data, media, and EnhanceMarkets shell code.
