Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,30 @@ Returns service health status.

---

### `GET /health/rpc`

Checks Soroban RPC reachability and current ledger.

**Response `200`**

```json
{
"rpc": "reachable",
"network": "mainnet",
"ledger": 54321678
}
```

#### Errors

| Status | Description |
| ------ | --------------------------------------- |
| `503` | Soroban RPC unreachable |
| `500` | Unexpected server error |

---


## Invoices

### `GET /invoices/:id`
Expand Down Expand Up @@ -304,6 +328,135 @@ Update the treasury approval threshold.

---

### `GET /api/treasury/on-hold-settlements`

Returns all settlements that are currently on hold.
A hold is placed when a signer flags a settlement as requiring manual review before
execution can proceed.

**Query parameters:**

| Parameter | Type | Required | Description |
|-----------|--------|----------|-----------------------------------------------|
| `page` | number | No | Page number (1-based, default: `1`) |
| `limit` | number | No | Results per page (default: `20`, max: `100`) |

**Response `200`**

```json
{
"settlements": [
{
"id": 7,
"merchant_address": "G...",
"amount": "5000000",
"approvals": [],
"approval_weight": 0,
"status": "OnHold",
"hold_reason": "Merchant KYC under review"
}
]
}
```

#### Errors

| Status | Description |
| ------ | ----------------------- |
| `500` | Database error |

---

### `POST /api/treasury/release-hold`

Releases a held settlement, restoring it to `Pending` so the normal approval and
execution flow can resume. Calls `release_hold` on the treasury contract.

See also: [`release_hold` in the Contract Interaction Guide](./contract-interaction-guide.md#release-a-hold).

#### Request body

```json
{ "settlement_id": 7 }
```

| Field | Type | Description |
| --------------- | ------ | ------------------------------ |
| `settlement_id` | number | Positive integer settlement ID |

**Response `200`**

```json
{
"id": 7,
"merchant_address": "G...",
"amount": "5000000",
"approvals": [],
"approval_weight": 0,
"status": "Pending",
"hold_reason": null,
"tx_hash": "abc123..."
}
```

#### Errors

| Status | Description |
| ------ | ------------------------------------------------- |
| `400` | `settlement_id` is not a positive integer |
| `409` | Settlement is not currently on hold |
| `422` | Soroban simulation or transaction failure |
| `503` | Missing required environment variables |
| `500` | Unexpected server error |

---

### `POST /api/treasury/escalate-hold`

Escalates a held settlement to the on-chain dispute-resolution flow.
Calls `raise_dispute` on the treasury contract and begins a multi-sig governance
vote among the configured signers.

See also: [`raise_dispute` in the Contract Interaction Guide](./contract-interaction-guide.md#raise-a-dispute).

#### Request body

```json
{
"settlement_id": 7,
"reason": "Merchant disputes the invoice amount"
}
```

| Field | Type | Required | Description |
| --------------- | ------ | -------- | -------------------------------------------------------- |
| `settlement_id` | number | Yes | Positive integer settlement ID |
| `reason` | string | No | Human-readable reason for escalation (max 512 chars) |

**Response `200`**

```json
{
"dispute_id": "7-1720000001000",
"settlement_id": "7",
"status": "Raised",
"settlement_status": "OnHold",
"tx_hash": "abc123..."
}
```

#### Errors

| Status | Description |
| ------ | ------------------------------------------------- |
| `400` | `settlement_id` is not a positive integer |
| `422` | Soroban simulation or transaction failure |
| `503` | Missing required environment variables |
| `500` | Unexpected server error |

---


## Invoice Settings

### `GET /api/invoice/grace-window`
Expand Down
79 changes: 79 additions & 0 deletions docs/contract-interaction-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,85 @@ curl -X POST http://localhost:3000/api/treasury/execute-settlement \

---


### Place a settlement on hold

Calls `hold_settlement` on the treasury contract, preventing execution until
explicitly released or escalated.

#### soroban-cli

```sh
soroban contract invoke \\
--id $TREASURY_CONTRACT \\
--source $SECRET_KEY \\
--rpc-url $RPC_URL \\
--network-passphrase "$NETWORK_PASSPHRASE" \\
-- hold_settlement \\
--signer $SOURCE_ACCOUNT \\
--settlement_id 7 \\
--reason "Awaiting KYC confirmation"
```

---

### Release a hold

Calls `release_hold` on the treasury contract, returning the settlement to `Pending`
so the normal approval and execution flow can resume.

#### soroban-cli

```sh
soroban contract invoke \\
--id $TREASURY_CONTRACT \\
--source $SECRET_KEY \\
--rpc-url $RPC_URL \\
--network-passphrase "$NETWORK_PASSPHRASE" \\
-- release_hold \\
--signer $SOURCE_ACCOUNT \\
--settlement_id 7
```

#### API

```sh
curl -X POST http://localhost:3000/api/treasury/release-hold \\
-H "Content-Type: application/json" \\
-d '{ "settlement_id": 7 }'
```

---

### Raise a dispute (escalate hold)

Calls `raise_dispute` on the treasury contract, escalating the hold to the
governance dispute-resolution flow and beginning a multi-sig vote.

#### soroban-cli

```sh
soroban contract invoke \\
--id $TREASURY_CONTRACT \\
--source $SECRET_KEY \\
--rpc-url $RPC_URL \\
--network-passphrase "$NETWORK_PASSPHRASE" \\
-- raise_dispute \\
--signer $SOURCE_ACCOUNT \\
--settlement_id 7 \\
--reason "Merchant disputes the invoice amount"
```

#### API

```sh
curl -X POST http://localhost:3000/api/treasury/escalate-hold \\
-H "Content-Type: application/json" \\
-d '{ "settlement_id": 7, "reason": "Merchant disputes the invoice amount" }'
```

---

### Get / set approval threshold

#### soroban-cli — read
Expand Down
38 changes: 38 additions & 0 deletions docs/dev-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,51 @@ INVOICE_CONTRACT_ID=$INVOICE_CONTRACT_ID
TREASURY_CONTRACT_ID=$TREASURY_CONTRACT_ID
COMPLIANCE_CONTRACT_ID=$COMPLIANCE_CONTRACT_ID
USDC_CONTRACT_ID=CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4
MONGO_URI=mongodb://localhost:27017/comebackhere
REDIS_URL=redis://localhost:6379
WEBHOOK_SECRET=<generate-a-32-char-or-longer-secret>
EOF
```

Before starting the backend, validate all required environment variables:

```sh
cd ../COMEBACKHERE
scripts/validate_backend_env.sh ../comebackhere-backend/.env
```

A missing or blank required variable causes the script to exit with a clear error message.
To also enforce the optional contract ID variables (e.g. in CI), run with `STRICT=1`:

```sh
STRICT=1 scripts/validate_backend_env.sh ../comebackhere-backend/.env
```

Then start the backend:

```sh
cd ../comebackhere-backend
cargo build && cargo run
```

Backend listens on `http://localhost:3000`.

#### Required backend variables

| Variable | Description |
|------------------|--------------------------------------------------------------------|
| `MONGO_URI` | MongoDB connection string (`mongodb://` or `mongodb+srv://`) |
| `REDIS_URL` | Redis connection string (`redis://`) |
| `WEBHOOK_SECRET` | HMAC secret for signing outgoing webhook payloads (≥ 32 chars) |

#### Optional contract integration variables

| Variable | Description |
|-------------------------|-----------------------------------------|
| `INVOICE_CONTRACT_ID` | Deployed invoice contract address |
| `TREASURY_CONTRACT_ID` | Deployed treasury contract address |
| `COMPLIANCE_CONTRACT_ID`| Deployed compliance contract address |

### Frontend

```sh
Expand Down
82 changes: 80 additions & 2 deletions scripts/deploy_mainnet.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,91 @@
#!/usr/bin/env bash
# Mainnet deployment entry point for COMEBACKHERE Protocol.
#
# Live deployment requires governance approval, multi-sig signing, and a recorded
# signing ceremony — this script intentionally refuses to submit transactions from
# a single local shell.
#
# Use --dry-run to print the planned actions (contracts, addresses, network config)
# without submitting any transaction. The output is formatted to be easy to paste
# into a deployment-checklist PR or issue.
#
# Usage:
# scripts/deploy_mainnet.sh --dry-run # preview only — zero network-mutating calls
# scripts/deploy_mainnet.sh # refuses; live deploy requires multi-sig ceremony
set -euo pipefail

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT_DIR"

echo "Mainnet deployment requires multi-sig approval and an external signing ceremony."
echo "Refusing to deploy from a single local shell."
DRY_RUN=0

for arg in "$@"; do
case "$arg" in
--dry-run) DRY_RUN=1 ;;
*)
echo "Unknown argument: $arg" >&2
echo "Usage: $0 [--dry-run]" >&2
exit 1
;;
esac
done

# ── resolve env ───────────────────────────────────────────────────────────────

# shellcheck disable=SC1091
source scripts/validate_env.sh .env.mainnet mainnet deployment

# ── dry-run mode ──────────────────────────────────────────────────────────────

if [ "$DRY_RUN" -eq 1 ]; then
ADMIN_PUBLIC_KEY="${ADMIN_PUBLIC_KEY:-<not set>}"
USDC_CONTRACT_ID="${USDC_CONTRACT_ID:-<not set>}"
TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"

cat <<DRYRUN
========================================================
COMEBACKHERE MAINNET DEPLOYMENT — DRY RUN
Generated: $TIMESTAMP
** No transactions will be submitted **
========================================================

NETWORK CONFIGURATION
STELLAR_NETWORK : ${STELLAR_NETWORK:-<not set>}
SOROBAN_RPC_URL : ${SOROBAN_RPC_URL:-<not set>}
SOROBAN_NETWORK_PASSPHRASE : ${SOROBAN_NETWORK_PASSPHRASE:-<not set>}

SIGNING AUTHORITY
ADMIN_PUBLIC_KEY : $ADMIN_PUBLIC_KEY

CONTRACT ADDRESSES
INVOICE_CONTRACT_ID : ${INVOICE_CONTRACT_ID:-<not set>}
TREASURY_CONTRACT_ID : ${TREASURY_CONTRACT_ID:-<not set>}
COMPLIANCE_CONTRACT_ID : ${COMPLIANCE_CONTRACT_ID:-<not set>}
USDC_CONTRACT_ID : $USDC_CONTRACT_ID

PLANNED ACTIONS
[1] Verify WASM hashes match deployment-issue expectations
[2] Verify Soroban RPC is reachable at ${SOROBAN_RPC_URL:-<not set>}
[3] Verify ADMIN_PUBLIC_KEY is funded and authorised on ${STELLAR_NETWORK:-mainnet}
[4] Deploy invoice contract → INVOICE_CONTRACT_ID
[5] Deploy treasury contract → TREASURY_CONTRACT_ID
[6] Deploy compliance contract → COMPLIANCE_CONTRACT_ID
[7] Initialize contracts with admin $ADMIN_PUBLIC_KEY
[8] Export deployed addresses to artifacts/addresses.json
[9] Run smoke tests (GET /health/rpc + low-value payment)

DRY RUN COMPLETE — review the above before running the signing ceremony.
Paste this output into the deployment-checklist PR as the pre-flight record.
========================================================
DRYRUN
exit 0
fi

# ── live deploy — refused ─────────────────────────────────────────────────────

echo "Mainnet deployment requires multi-sig approval and an external signing ceremony."
echo "Refusing to deploy from a single local shell."
echo ""
echo "Run with --dry-run to preview planned actions without submitting transactions."
echo "See docs/MAINNET_DEPLOYMENT.md for the full ceremony checklist."
exit 1
Loading
Loading