<!doctype html>

<html lang="en">

<head>

  <meta charset="utf-8" />

  <meta name="viewport" content="width=device-width, initial-scale=1" />

  <title>Mini Solana Store (devnet)</title>

  <style>

    :root { --bg:#0b1020; --card:#121935; --ink:#e6ecff; --muted:#9fb0ff; --accent:#6ee7b7; }

    body { margin:0; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto; background:linear-gradient(120deg,#0b1020,#0f1634); color:var(--ink); }

    .wrap { max-width: 880px; margin: 40px auto; padding: 0 20px; }

    header { display:flex; gap:16px; align-items:center; justify-content:space-between; margin-bottom:24px; }

    .btn { background: #2b356b; color: var(--ink); border:1px solid #3b4786; padding:10px 14px; border-radius:14px; cursor:pointer; }

    .btn[disabled] { opacity:.5; cursor:not-allowed; }

    .row { display:grid; grid-template-columns: repeat(auto-fit,minmax(240px,1fr)); gap:16px; }

    .card { background:var(--card); border:1px solid #273163; padding:16px; border-radius:18px; box-shadow:0 10px 30px rgba(0,0,0,.25); }

    .price { color: var(--accent); font-weight:700; }

    .muted { color: var(--muted); font-size: 12px; }

    .badge { font-size: 12px; padding:4px 8px; border-radius:999px; background:#1b2552; border:1px solid #2a3771; display:inline-block; }

    a.explorer { color:#9ad5ff; text-decoration: underline; }

    .stack { display:flex; gap:8px; align-items:center; flex-wrap:wrap; }

    footer { margin-top:28px; font-size:12px; color:#b7c4ff; opacity:.85 }

    code { background:#0c1329; border:1px solid #1e2a58; padding:2px 6px; border-radius:8px; }

  </style>

  <!-- Solana web3.js (IIFE build exposes global solanaWeb3) -->

  <script src="https://unpkg.com/@solana/web3.js@1.95.3/lib/index.iife.min.js"></script>

</head>

<body>

  <div class="wrap">

    <header>

      <div class="stack">

        <h1 style="margin:0">Mini Solana Store</h1>

        <span class="badge">devnet</span>

      </div>

      <div class="stack">

        <button id="connect" class="btn">Connect Wallet</button>

        <button id="airdrop" class="btn" title="Devnet only">Airdrop 1 SOL</button>

      </div>

    </header>


    <div class="card" id="walletPanel">

      <div class="stack" style="justify-content:space-between">

        <div>

          <div>Wallet: <span id="addr">—</span></div>

          <div>Balance: <span id="bal">—</span> SOL</div>

          <div class="muted">Network should be <b>devnet</b>. Switch in Phantom if needed.</div>

        </div>

        <div><button class="btn" id="refresh">Refresh</button></div>

      </div>

      <div id="status" class="muted" style="margin-top:10px"></div>

      <div id="lastTx" style="margin-top:6px"></div>

    </div>


    <h2 style="margin:16px 0 8px">Items for sale</h2>

    <div class="row" id="items"></div>


    <footer>

      <p>

        This is a single HTML file. It connects Phantom, requests a devnet airdrop, and sends a SOL transfer to a merchant address.

        Edit prices/labels inside <code>ITEMS</code> below. When ready to go real, change <code>RPC_URL</code> to a mainnet RPC and remove airdrop.

      </p>

    </footer>

  </div>


<script>

(async function(){

  // ======== Config you can edit ========

  const RPC_URL = 'https://api.devnet.solana.com'; // keep devnet for testing

  const MERCHANT = new solanaWeb3.PublicKey('7wqLk9nJG2qWw7HjC8R8xC2xJ2v2m7R9y7xj2o9V3r3o'); // replace with your public key

  const ITEMS = [

    { id:'cap',  name:'Collection Connection Cap',  priceSol: 0.02, img: '', desc:'Embroidered dad cap' },

    { id:'tee',  name:'Vintage Graphic Tee',         priceSol: 0.05, img: '', desc:'Soft, pre‑shrunk cotton' },

    { id:'card', name:'’86 Fleer Replica Print',     priceSol: 0.03, img: '', desc:'Limited run 8×10' },

  ];

  // =====================================


  const conn = new solanaWeb3.Connection(RPC_URL, 'confirmed');

  const $ = s => document.querySelector(s);

  const $$ = s => document.querySelectorAll(s);

  const set = (el, v) => (el.textContent = v);

  const short = a => a ? a.slice(0,4)+'…'+a.slice(-4) : '—';


  const ui = {

    connect: $('#connect'), airdrop: $('#airdrop'), refresh: $('#refresh'),

    addr: $('#addr'), bal: $('#bal'), status: $('#status'), lastTx: $('#lastTx'), items: $('#items')

  };


  // Render items

  ui.items.innerHTML = ITEMS.map(it => `

    <div class="card">

      <div style="font-weight:600">${it.name}</div>

      <div class="muted" style="margin:6px 0 10px">${it.desc}</div>

      <div class="price">${it.priceSol} SOL</div>

      <div style="margin-top:10px" class="stack">

        <button class="btn buy" data-id="${it.id}">Buy with SOL</button>

      </div>

    </div>`).join('');


  const provider = window.solana; // Phantom injects this

  let pubkey = null;


  function assertProvider(){

    if(!provider){

      ui.status.innerHTML = 'Phantom not found. Install it from the extension store.';

      throw new Error('No provider');

    }

  }


  async function refresh(){

    if(!pubkey) return;

    const lamports = await conn.getBalance(new solanaWeb3.PublicKey(pubkey));

    set(ui.bal,(lamports/solanaWeb3.LAMPORTS_PER_SOL).toFixed(4));

  }


  async function connect(){

    assertProvider();

    const res = await provider.connect();

    pubkey = res.publicKey.toString();

    set(ui.addr, short(pubkey));

    await refresh();

    ui.status.textContent = 'Connected.';

  }


  async function airdrop(){

    if(!pubkey){ ui.status.textContent = 'Connect first.'; return; }

    ui.status.textContent = 'Requesting 1 SOL airdrop (devnet)…';

    const sig = await conn.requestAirdrop(new solanaWeb3.PublicKey(pubkey), solanaWeb3.LAMPORTS_PER_SOL);

    await conn.confirmTransaction(sig, 'confirmed');

    await refresh();

    ui.status.textContent = 'Airdrop received.';

  }


  async function buy(item){

    if(!pubkey){ ui.status.textContent = 'Connect first.'; return; }

    try{

      ui.status.textContent = `Creating transaction for ${item.name}…`;

      const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash();

      const tx = new solanaWeb3.Transaction({ feePayer: new solanaWeb3.PublicKey(pubkey), blockhash, lastValidBlockHeight });

      tx.add(solanaWeb3.SystemProgram.transfer({ fromPubkey: new solanaWeb3.PublicKey(pubkey), toPubkey: MERCHANT, lamports: Math.round(item.priceSol * solanaWeb3.LAMPORTS_PER_SOL) }));


      const signed = await provider.signAndSendTransaction(tx);

      ui.lastTx.innerHTML = `Last payment: <a class="explorer" target="_blank" rel="noreferrer" href="https://explorer.solana.com/tx/${signed.signature}?cluster=devnet">View in Explorer</a>`;

      ui.status.textContent = 'Submitted. Waiting for confirmation…';

      await conn.confirmTransaction({ signature: signed.signature, blockhash, lastValidBlockHeight }, 'confirmed');

      ui.status.textContent = 'Payment confirmed ✅';

      await refresh();

    }catch(e){ ui.status.textContent = 'Payment failed: ' + (e.message || e); }

  }


  // Wire up UI

  ui.connect.onclick = connect;

  ui.airdrop.onclick = airdrop;

  ui.refresh.onclick = refresh;

  ui.items.addEventListener('click', (ev)=>{

    const btn = ev.target.closest('.buy');

    if(!btn) return;

    const item = ITEMS.find(x => x.id === btn.dataset.id);

    buy(item);

  });

})();

</script>

</body>

</html>