# MesharePay

A lightweight, single-file Java wallet that pairs with **MeshareChain** / **MeshareRank**. It runs a local web UI and doubles as a federation node other MesharePay instances can sync with.

Single-file, Java 8 compatible, no external dependencies. Uses `com.sun.net.httpserver.HttpServer` for the embedded web server and AWT only to open the default browser on launch.

## How it works

### Wallet / keys
- You bring your own **secp256r1 (P-256)** key pair  MesharePay never generates keys.
- Keys can be pasted into the UI (PEM or raw Base64), or auto-loaded from `public_key.txt` (X.509 SubjectPublicKeyInfo) and `private_key.txt` (PKCS#8) in the working directory.
- The private key stays in memory / on local disk only  it is **never** served over HTTP.
- A key's canonical network address is `Base64(X.509 SubjectPublicKeyInfo DER bytes)`. Whatever format a key is pasted in, it's normalized to this form so the same key always maps to the same address.

### Points / balance
- **Earned points** = however many times a key has been found on a server, per MeshareRank's `consensus.txt` (`<public_key>:<count>` per line). MesharePay fetches this file from every peer in `servers.txt` and keeps the highest count seen per key. It also tallies local, already-confirmed `blocks/` files as a conservative floor.
- **Spent points** = the sum of a key's transactions this ledger accepts. Every node publishes `points/<sha256(key)>.json` snapshots (indexed by `points.txt`); the highest "spent" figure reported by any peer is treated as a floor, so a node with stale/incomplete gossip won't allow a double-spend against its own view.

```
balance(key) = max(0, earned(key) - max(locallyAcceptedSpent(key), peerReportedSpent(key)))
```

### Transactions / double-spend protection
- A transaction is a small JSON document: `id, from, to, amount, nonce, timestamp, signature`.
- Signature: `SHA256withECDSA` over the canonical string `from|to|amount|nonce|timestamp`, Base64-encoded.
- `id` is the SHA-256 hex digest of that same canonical string, so any peer can verify it without trusting the sender.
- Transactions are stored one-per-file as `transactions/<id>.json`, written with `File.createNewFile()` and never overwritten.
- Every known transaction (local or gossiped in) is replayed per-sender in `(timestamp, id)` order. A transaction is accepted only while the sender's running total stays within their earned points; otherwise it's marked rejected as a double-spend. Acceptance is a local, recomputed opinion  not baked into the transaction file itself.

### Networking
All peer communication is plain **HTTP GET**  nothing is ever POSTed to a peer:
- This node **publishes**: `consensus.txt` (if present), `transactions.txt` / `transactions/*.json`, `points.txt` / `points/*.json`.
- This node **pulls** the same three resource types from every server listed in `servers.txt`.

## Running it

```bash
javac MesharePay.java
java MesharePay [port]
```

- `port` is optional; defaults to **8097**.
- On launch, MesharePay starts its embedded HTTP server and opens your default browser to `http://localhost:<port>/`.
- The same URL is what you'd add to another node's `servers.txt` to federate with it.
- Stop the app with `Ctrl+C`.

## Configuration files (working directory)

| File | Purpose |
|---|---|
| `servers.txt` | List of peer node URLs to sync with (one per line) |
| `consensus.txt` | MeshareRank-produced `<public_key>:<count>` earned-points data |
| `public_key.txt` | This node's wallet public key (X.509 SPKI, PEM or Base64) |
| `private_key.txt` | This node's wallet private key (PKCS#8)  local only, never transmitted |
| `blocks/` | MeshareChain's confirmed block files, scanned for a local earned-points floor |
| `transactions/` | One JSON file per transaction (`<id>.json`) |
| `transactions.txt` | Index of known transaction IDs, published for peers |
| `points/` | One JSON snapshot per key (`<sha256(key)>.json`) of earned/spent points |
| `points.txt` | Index of published points snapshots |

## Web UI & API

The embedded server exposes a browser dashboard plus a JSON/SSE API:

**UI / control**
- `GET /`  dashboard (wallet, balance, transactions, log, server list)
- `GET /api/state`  current app state snapshot
- `GET /api/events`  Server-Sent Events stream (log lines, status, wallet/tx updates)
- `POST /api/run` / `POST /api/stop`  start/stop the sync loop
- `GET|POST /api/file`  view/edit a config file (e.g. `servers.txt`)
- `POST /api/servers/reload`  reload `servers.txt`

**Wallet**
- `POST /api/wallet/keys`  set wallet keys (optionally persist to disk)
- `POST /api/wallet/keys/load`  load keys from `public_key.txt` / `private_key.txt`
- `POST /api/wallet/keys/clear`  clear keys from memory
- `GET /api/wallet/balance`  current balance for the loaded wallet
- `GET /api/wallet/transactions`  this wallet's transaction history
- `POST /api/send`  create, sign, and broadcast a new transaction

**Federation (served to peers, GET only)**
- `GET /consensus.txt`
- `GET /transactions.txt`, `GET /transactions/<id>.json`
- `GET /points.txt`, `GET /points/<hash>.json`

## Requirements

- Java 8 or later
- No external libraries  everything (HTTP server, JSON handling, crypto) uses the JDK standard library
