diff options
| author | Adam Soltys <[email protected]> | 2026-07-04 07:53:03 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-07-04 07:53:03 -0700 |
| commit | 2da22a3dc82bc8c0beb456097c2749ebc02d8017 (patch) | |
| tree | 8560c3a3bb161045e57031bce0e796544653f6be /tools | |
| parent | d8da74e50a374d59629b8ec8731e8cb38bc6b42e (diff) | |
| download | coinosv3-2da22a3dc82bc8c0beb456097c2749ebc02d8017.tar.gz coinosv3-2da22a3dc82bc8c0beb456097c2749ebc02d8017.zip | |
Gift claim: make the wallet chooser read as a choice
The existing-wallet buttons looked like inert inputs. Now: a "Receive
into one of your wallets:" label, a chevron on each wallet row so it
reads as tappable, and an "or" divider before the new-wallet button.
(tools/ark/gift-shot.js: screenshot harness that mints a real regtest
gift and opens its link.)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/ark/gift-shot.js | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/tools/ark/gift-shot.js b/tools/ark/gift-shot.js new file mode 100644 index 0000000..9874e8c --- /dev/null +++ b/tools/ark/gift-shot.js @@ -0,0 +1,82 @@ +// Screenshot the gift-claim wallet chooser: mint a real gift from a funded +// wallet, open its link in the same browser (wallet 1 still in session), +// capture the "choose where to receive" screen. +import { spawn, execSync } from 'node:child_process'; +import puppeteer from 'puppeteer-core'; +import { generateMnemonic } from '@scure/bip39'; +import { wordlist } from '@scure/bip39/wordlists/english'; + +const PORT = 5199; +const APP = `http://localhost:${PORT}`; +const BCLI = `bitcoin-cli -regtest -datadir=${process.env.HOME}/ark-regtest/bitcoind -rpcport=18543 -rpcwallet=miner`; +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); +const sh = (cmd) => execSync(cmd, { shell: '/bin/bash' }).toString().trim(); + +const dev = spawn('bun', ['run', 'dev'], { cwd: process.env.HOME + '/halwallet', env: { ...process.env, PORT: String(PORT) }, stdio: 'ignore' }); +for (let i = 0; i < 30; i++) { try { if ((await fetch(APP)).ok) break; } catch {} await sleep(500); } + +const browser = await puppeteer.launch({ executablePath: '/usr/bin/google-chrome', headless: 'new', args: ['--no-sandbox'] }); +const page = await browser.newPage(); +await page.setViewport({ width: 420, height: 860, deviceScaleFactor: 2 }); +const clickText = (sel, text) => page.evaluate((sel, text) => { + const el = [...document.querySelectorAll(sel)].find((e) => e.textContent.trim().toLowerCase().includes(text.toLowerCase())); + if (el) { el.click(); return true; } return false; +}, sel, text); +const waitText = async (text, ms = 20000) => { + for (let i = 0; i < ms / 250; i++) { + if (await page.evaluate((t) => document.body.innerText.toLowerCase().includes(t.toLowerCase()), text)) return true; + await sleep(250); + } + return false; +}; + +await page.goto(APP, { waitUntil: 'domcontentloaded' }); +await page.evaluate(() => { + localStorage.setItem('btc-wallet-network', 'regtest'); + localStorage.setItem('btc-wallet-source:regtest', JSON.stringify({ id: 'custom', url: 'http://localhost:30002' })); + localStorage.setItem('btc-wallet-ark-provider:regtest', 'local'); +}); +await page.reload({ waitUntil: 'domcontentloaded' }); +await sleep(500); +await clickText('button', 'Import existing'); +await sleep(200); +await page.type('textarea', generateMnemonic(wordlist)); +await clickText('button', 'Open wallet'); +await waitText('receive'); + +// fund on-chain, confirmed +const addr = await page.evaluate(() => document.querySelector('.addr-box')?.textContent.trim()); +sh(`${BCLI} sendtoaddress ${addr} 0.0005`); +sh(`${BCLI} generatetoaddress 1 $(${BCLI} getnewaddress) >/dev/null`); +await waitText('50,000', 30000); +if (await page.evaluate(() => document.body.innerText.includes('Payment received'))) { + await clickText('.card', 'Payment received'); + await sleep(300); +} + +// make a 2000-sat gift +await clickText('.tabs button', 'Send'); +await sleep(300); +await clickText('button', 'Gift some Bitcoin'); +await sleep(300); +const amtInput = await page.evaluateHandle(() => [...document.querySelectorAll('input[type="number"]')][0]); +await amtInput.asElement().type('2000'); +await clickText('button', 'Create gift link'); +await sleep(500); +if (await page.evaluate(() => document.body.innerText.includes('Lock the whole coin'))) { + await clickText('button', 'Lock the whole coin'); +} +await waitText('/g/', 20000); +const link = await page.evaluate(() => + [...document.querySelectorAll('.addr-box')].map((e) => e.textContent.trim()).find((x) => x.includes('/g/'))); +console.log('gift link:', (link || '').slice(0, 50) + '…'); + +// open the gift link — wallet 1 exists, so the chooser should appear +await page.goto(link, { waitUntil: 'domcontentloaded' }); +const shown = await waitText('Choose where', 15000); +console.log('chooser shown:', shown); +await sleep(400); +await page.screenshot({ path: '/tmp/gift-choose.png' }); +console.log('done'); +await browser.close(); +dev.kill(); |
