# SoulWall

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

Current public build: **v1.3**, dated **2026-05-05**.

## Master Build Workflow

The root files in this repo are the master build:

- `index.html`
- `site.css`
- `app.js`
- `functions/api/soulwall/*.js`
- `worker.js`

After changing any of those, run:

```bash
npm run rebuild
```

That refreshes:

- `public/soulwall/` public site copies
- `source/` and `public/soulwall/source/` public source mirrors
- `public/soulwall/downloads/soulwall-public-build-v1.3-2026-05-05.zip`
- embedded SoulWall JS/CSS inside `worker.js`
- `COPY-PASTE-THIS-WORKER.js`
- `dist/livenewsindex-worker-soulwall-paste.js`

See [`docs/soulwall-deployment-notes.md`](./docs/soulwall-deployment-notes.md) for the current deployment rule set.

## 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.
- `developers/index.html` - self-hosted developer shelf for the public build.
- `downloads/soulwall-public-build-v1.3-2026-05-05.zip` - sanitized downloadable v1.3 build folder.
- `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`.

## Provider Proofs

SoulWall now supports two crypto proof patterns:

- `giveth` - users donate on the official Giveth project page, then SoulWall verifies the returned Polygon transaction hash server-side.
- `tgb` - SoulWall calls The Giving Block server-to-server, mints a fresh charity deposit address on selection, stores the trusted route in KV, and then verifies the returned transaction hash against that route or a cached provider proof.

Confirmed proofs are deduplicated and written to the public ledger. SoulWall does not custody funds, receive wallet payments, or act as the payment processor.

## Public API

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

Returns the current browser session state.

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

Returns configured donation projects for the active charity network.

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

Creates a donation intent for authenticated users. For TGB-backed causes, this also mints and stores a trusted donation address route.

### `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",
  "clientId": "optional-deployment-id",
  "deploymentTitle": "optional-deployment-title",
  "deploymentDescription": "optional-deployment-description",
  "sourceWebsite": "https://example.com"
}
```

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

Verifies a transaction hash against the trusted The Giving Block route minted during `POST /api/soulwall/intent`.

Payload:

```json
{
  "txHash": "0x...",
  "intentId": "required-intent-id",
  "clientId": "optional-deployment-id",
  "deploymentTitle": "optional-deployment-title",
  "deploymentDescription": "optional-deployment-description",
  "sourceWebsite": "https://example.com"
}
```

### `POST /api/soulwall/tgb-webhook`

Receives encrypted The Giving Block webhook notifications, decrypts them server-side, and stores the resulting proof in KV for fast session restoration.

### `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",
  "deploymentTitle": "Premium Research Access",
  "deploymentDescription": "Unlocks the members-only dashboard for 24 hours.",
  "sourceWebsite": "https://example.com",
  "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

For the full working package, open `/developers/` on the live site or download `/downloads/soulwall-public-build-v1.3-2026-05-05.zip`.

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"
  data-soulwall-title="Premium Research Access"
  data-soulwall-description="Unlocks the members-only dashboard for 24 hours."
  data-soulwall-website="https://example.com"></script>
```

If a deployment includes `data-soulwall-title`, `data-soulwall-description`, and `data-soulwall-website` on the widget, or the equivalent server-side env vars in an active deployment, SoulWall credits those details on the master homepage ledger.

For full-page SoulWall deployments, the browser client also reads these optional meta tags automatically and forwards them during verify calls:

```html
<meta name="soulwall:client-id" content="live-news-index">
<meta name="soulwall:deployment-title" content="Live News Index Opinion Access">
<meta name="soulwall:deployment-description" content="Unlocks opinion articles for a 24-hour session.">
<meta name="soulwall:source-website" content="https://livenewsindex.com">
```

After a provider confirms a donation, report it:

```js
await SoulWall.pingDonation({
  txHash: '0x...',
  amountUsd: 1.25,
  projectName: 'Project Name',
  deploymentTitle: 'Premium Research Access',
  deploymentDescription: 'Unlocks the members-only dashboard for 24 hours.',
  sourceWebsite: 'https://example.com'
});
```

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

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

### Active Deployment Credit Fields

For full SoulWall deployments running on a partner site, set these env vars so confirmed donations are credited on the SoulWall homepage ledger even when the browser widget is not the writer of record:

```bash
SOULWALL_LEDGER_CLIENT_ID="my-product"
SOULWALL_DEPLOYMENT_TITLE="Premium Research Access"
SOULWALL_DEPLOYMENT_DESCRIPTION="Unlocks the members-only dashboard for 24 hours."
SOULWALL_SOURCE_WEBSITE="https://example.com"
```

## 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, the current public gate demo, 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.
