/** * LPS-1 public mint button — x402 settle → yield parcel in Donkai profile. * Usage: GMIIELpsMint.renderButton(container, { briefId, title, compact }) */ (function (global) { 'use strict'; function esc(s) { return String(s || '') .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function setBtnState(btn, state, label) { btn.disabled = state === 'loading'; btn.classList.remove('lps-mint--loading', 'lps-mint--done', 'lps-mint--error'); if (state) btn.classList.add('lps-mint--' + state); btn.textContent = label; } async function activateYield(briefId, receipt) { const headers = { 'Content-Type': 'application/json', Accept: 'application/json' }; if (receipt) headers['X-Payment-Receipt'] = receipt; const res = await fetch('/api/lps/yield-activate', { method: 'POST', headers: headers, body: JSON.stringify({ brief_id: briefId }), }); const data = await res.json().catch(function () { return {}; }); return { res: res, data: data }; } async function mintBrief(briefId, btn, opts) { if (!briefId || !btn) return; setBtnState(btn, 'loading', 'Settling…'); try { let { res, data } = await activateYield(briefId, null); if (res.status === 402 && data.payment_required) { const amt = (data.payment && data.payment.amount_human) || '0.10 ATP'; const receipt = global.prompt( 'Mint requires x402 settlement (' + amt + ' on Apostle chain 7332).\nPaste X-Payment-Receipt tx hash, or Cancel to use preview:\n\nLeave blank + OK for preview mint.' ); if (receipt === null) { setBtnState(btn, null, opts.compact ? 'Mint' : '⚡ Mint + Yield'); return; } if (receipt.trim()) { ({ res, data } = await activateYield(briefId, receipt.trim())); } else { ({ res, data } = await fetch('/api/lps/yield-activate?test=true', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Payment-Test': 'true' }, body: JSON.stringify({ brief_id: briefId, preview: true }), }).then(function (r) { return r.json().then(function (d) { return { res: r, data: d }; }); })); } } if (!res.ok && !data.ok) { setBtnState(btn, 'error', 'Mint failed'); btn.title = data.error || data.reason || 'yield-activate error'; return; } setBtnState(btn, 'done', '✓ Yield live'); btn.title = (data.treasury_yield_hook || data.treasury_yield || 'Yield active') + (data.xrpl_parcel_tx ? ' · ' + data.xrpl_parcel_tx : ''); var badge = btn.parentElement && btn.parentElement.querySelector('.lps-yield-badge'); if (!badge && btn.parentElement) { badge = document.createElement('span'); badge.className = 'lps-yield-badge'; btn.parentElement.appendChild(badge); } if (badge) { badge.textContent = data.metaverse_badge || '🛡️ Yield NPC'; } global.dispatchEvent( new CustomEvent('gmiie-yield-activated', { detail: { briefId: briefId, yield: data } }) ); } catch (e) { setBtnState(btn, 'error', 'Error'); btn.title = e.message; } } function renderButton(container, opts) { if (!container) return null; opts = opts || {}; var briefId = opts.briefId || opts.brief_id || opts.id; if (!briefId) return null; var wrap = document.createElement('div'); wrap.className = 'lps-mint-wrap' + (opts.compact ? ' lps-mint-wrap--compact' : ''); var btn = document.createElement('button'); btn.type = 'button'; btn.className = 'lps-mint-btn'; btn.setAttribute('data-brief-id', briefId); btn.setAttribute('aria-label', 'Mint brief and activate yield: ' + (opts.title || briefId)); btn.textContent = opts.compact ? 'Mint' : '⚡ Mint + Yield'; btn.addEventListener('click', function () { mintBrief(briefId, btn, opts); }); wrap.appendChild(btn); if (opts.lps1Id) { var pill = document.createElement('span'); pill.className = 'lps-mint-pill'; pill.textContent = '🔒 ' + opts.lps1Id; wrap.appendChild(pill); } container.appendChild(wrap); return btn; } global.GMIIELpsMint = { mintBrief: mintBrief, renderButton: renderButton, activateYield: activateYield, }; })(typeof window !== 'undefined' ? window : globalThis);