Initial commit — Performance West telecom compliance platform

Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
justin 2026-04-27 06:54:22 -05:00
commit f8cd37ac8c
1823 changed files with 145167 additions and 0 deletions

View file

@ -0,0 +1,127 @@
"""SHKeeper client — thin wrapper over the self-hosted SHKeeper REST API.
SHKeeper (https://github.com/vsys-host/shkeeper.io) is our crypto payment
gateway. It exposes one REST endpoint per coin at
{SHKEEPER_URL}/api/v1/{coin}/...
with bearer auth via X-Shkeeper-Api-Key header.
We use it for two things post-webhook:
1. payout() withdraw coins from the SHKeeper hot wallet to an
external address (either a Coinbase Prime deposit
address for offramp, or the cold wallet for sweeps).
2. balance() read the current hot-wallet balance for sweep sizing.
SHKeeper exposes a /payout endpoint; exact shape varies by coin but
follows the pattern documented in the project's API README. Confirm
shape against the running instance during first real test we stub
with sensible defaults and will iterate.
"""
from __future__ import annotations
import logging
import os
from dataclasses import dataclass
from decimal import Decimal
from typing import Optional
import httpx
logger = logging.getLogger(__name__)
SHKEEPER_URL = os.environ.get("SHKEEPER_URL", "http://127.0.0.1:5000")
SHKEEPER_API_KEY = os.environ.get("SHKEEPER_API_KEY", "")
@dataclass
class PayoutResult:
withdraw_id: str
tx_hash: Optional[str]
fee_coin: Decimal = Decimal("0")
raw: dict = None # type: ignore[assignment]
@dataclass
class BalanceResult:
balance_coin: Decimal
balance_usd: Decimal # SHKeeper returns fiat equivalent on balance
updated_at: Optional[str] = None
class SHKeeperError(Exception):
"""Any SHKeeper API failure."""
class SHKeeperClient:
def __init__(
self,
base_url: Optional[str] = None,
api_key: Optional[str] = None,
):
self.base = base_url or SHKEEPER_URL
self.api_key = api_key or SHKEEPER_API_KEY
if not self.api_key:
logger.warning(
"SHKeeperClient: SHKEEPER_API_KEY empty — calls will fail",
)
async def payout(
self,
*, coin: str, destination: str, amount: Decimal,
) -> PayoutResult:
"""POST /api/v1/{coin}/payout — withdraw to an external address.
Request body (per SHKeeper docs):
{"destination": "<addr>", "amount": "<decimal>"}
Response includes a withdraw_id + eventually a tx_hash.
"""
path = f"/api/v1/{coin.lower()}/payout"
body = {
"destination": destination,
"amount": str(amount),
}
resp = await self._request("POST", path, json_body=body)
return PayoutResult(
withdraw_id=str(resp.get("withdraw_id") or resp.get("id") or ""),
tx_hash=resp.get("tx_hash") or resp.get("txid"),
fee_coin=Decimal(str(resp.get("fee") or "0")),
raw=resp,
)
async def balance(self, coin: str) -> BalanceResult:
"""GET /api/v1/{coin}/balance — current hot-wallet balance."""
path = f"/api/v1/{coin.lower()}/balance"
resp = await self._request("GET", path)
return BalanceResult(
balance_coin=Decimal(str(resp.get("balance") or "0")),
balance_usd=Decimal(str(resp.get("balance_usd") or resp.get("fiat_balance") or "0")),
updated_at=resp.get("updated_at"),
)
async def withdrawal_status(self, coin: str, withdraw_id: str) -> dict:
"""GET /api/v1/{coin}/payout/{id} — poll for confirmation."""
path = f"/api/v1/{coin.lower()}/payout/{withdraw_id}"
return await self._request("GET", path)
async def _request(
self, method: str, path: str,
*, json_body: Optional[dict] = None,
) -> dict:
url = f"{self.base}{path}"
headers = {
"X-Shkeeper-Api-Key": self.api_key,
"Content-Type": "application/json",
}
try:
async with httpx.AsyncClient(timeout=30.0) as client:
resp = await client.request(method, url, headers=headers, json=json_body)
except httpx.HTTPError as exc:
raise SHKeeperError(f"SHKeeper request failed: {exc}") from exc
if resp.status_code >= 400:
raise SHKeeperError(
f"SHKeeper {method} {path}{resp.status_code}: {resp.text[:300]}",
)
try:
return resp.json()
except ValueError:
return {}