- #3 usePersonalContext decrypts the Stash ON DEMAND (unlockStash, called by getMyStash) instead of never — 'what's in my stash?' is now correct, while the globally-mounted guide still never decrypts on mount. stashRef avoids the stale-closure bug. - #4 new self-contained action draft wtb_gear (NIP-99 listing_type=wtb) — a 'wanted' gear ad. SYSTEM_PROMPT + tool handler + publish branch. - #5 panel header shows 'Pro · Nd' days left (title = exact expiry). - #6 tier picker computes live USD via useExchangeRate; removed the hardcoded ~$60k/BTC usd field from PRO_TIERS. - #7 copy: 'skate status' not 'spot status'; trip planning stated as free.
59 lines
2.5 KiB
TypeScript
59 lines
2.5 KiB
TypeScript
/**
|
|
* Sasquatch Pro — pricing tiers + shared constants.
|
|
* ─────────────────────────────────────────────────────────────────────────────
|
|
* Pro is a Lightning "supporter pass" that unlocks Sasquatch's personal
|
|
* assistant, action-drafting, priority model, and perks. Payment goes to the
|
|
* platform Lightning address via a NIP-57 zap, and access is verified two ways:
|
|
*
|
|
* 1. STRONG (preferred): a kind-9735 zap receipt from the platform's Lightning
|
|
* provider, bound to the paying user's npub — unforgeable by the user.
|
|
* 2. FALLBACK: a self-signed kind-32671 membership receipt (used only if the
|
|
* provider doesn't publish zap receipts), which references the payment so a
|
|
* future verifier can validate it retroactively.
|
|
*/
|
|
|
|
import type { NostrEvent } from '@nostrify/nostrify';
|
|
|
|
/** Platform Lightning address that receives Pro payments (same as the fee address). */
|
|
export { PLATFORM_LIGHTNING_ADDRESS as PRO_LIGHTNING_ADDRESS } from '@/lib/platform';
|
|
|
|
/** Proof of Pro sent to the AI proxy so its gate can re-verify server-side. */
|
|
export interface ProProof {
|
|
receipts: NostrEvent[];
|
|
grants: NostrEvent[];
|
|
}
|
|
|
|
export interface ProTier {
|
|
id: string;
|
|
label: string;
|
|
days: number;
|
|
sats: number;
|
|
/** Marketing flag. */
|
|
badge?: string;
|
|
popular?: boolean;
|
|
}
|
|
|
|
/** The four supporter tiers. Kept deliberately small to avoid choice paralysis. */
|
|
export const PRO_TIERS: ProTier[] = [
|
|
{ id: '7d', label: '7 days', days: 7, sats: 2000, badge: 'Try it' },
|
|
{ id: '1m', label: '1 month', days: 30, sats: 5000 },
|
|
{ id: '3m', label: '3 months', days: 90, sats: 12000, badge: '20% off', popular: true },
|
|
{ id: '1y', label: '1 year', days: 365, sats: 36000, badge: 'Best value · 40% off' },
|
|
];
|
|
|
|
export function tierById(id: string): ProTier | undefined {
|
|
return PRO_TIERS.find((t) => t.id === id);
|
|
}
|
|
|
|
/** Seconds in a day. */
|
|
export const DAY_SECONDS = 24 * 60 * 60;
|
|
|
|
/**
|
|
* Owner-grant fallback (NIP-32 label). If the Lightning provider ever stops
|
|
* publishing zap receipts, Pro can still be granted by the platform owner
|
|
* publishing a kind-1985 label in this namespace, tagged to the user with an
|
|
* `expiry` (unix seconds). Trusted because it is authored by an owner pubkey —
|
|
* and unforgeable by the user, unlike the self-signed kind-32671 receipt.
|
|
*/
|
|
export const PRO_LABEL_NAMESPACE = 'org.skatespots.pro';
|
|
export const PRO_LABEL_VALUE = 'pro';
|