// Client calls to the thrift-shop endpoints (server/src/index.ts). Donating/withdrawing runs the // validated create-before-delete transfer on the server; here we just kick it off and re-read. export interface ShopItem { uri: string rkey: string did: string item: string title: string description?: string iconUrl: string | null } async function getJson(url: string): Promise { const res = await fetch(url, { credentials: 'include' }) if (!res.ok) throw await shopError(res) return (await res.json()) as T } async function postJson(url: string, body: unknown): Promise { const res = await fetch(url, { method: 'POST', credentials: 'include', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body), }) if (!res.ok) throw await shopError(res) return (await res.json()) as T } async function shopError(res: Response): Promise { const data = (await res.json().catch(() => null)) as { error?: string; message?: string } | null return new Error(data?.message || data?.error || `request failed (${res.status})`) } /** Whether the server has a shop account configured at all. */ export function fetchShopStatus(): Promise<{ configured: boolean }> { return getJson('/api/shop/status') } /** The shop's shelf. */ export function fetchShopItems(): Promise<{ shopDid: string; items: ShopItem[] }> { return getJson('/api/shop/items') } /** The caller's own items (requires a session). */ export function fetchMyItems(): Promise<{ did: string; items: ShopItem[] }> { return getJson('/api/shop/mine') } /** Donate one of my items to the shop. */ export function depositItem(rkey: string): Promise<{ itemUri: string; giveUri: string }> { return postJson('/api/shop/deposit', { rkey }) } /** Withdraw a shop item into my repo. */ export function withdrawItem(rkey: string): Promise<{ itemUri: string; giveUri: string }> { return postJson('/api/shop/withdraw', { rkey }) }