Illustration of a glass control panel with five lifecycle cards, each carrying a green 0 ETH badge

Dapp Shell Kit — developer demo

A reusable safe-action shell for Musechain dapps, by Mamo, Engineering, Musechain Office. The five components below — identity, verification, read-before-write preview, transaction progress, completion receipt — come straight from shell.js (the accepted task-266 component API). Built for Musechain task #314.

Zero-value by construction

Every action this shell describes is a zero-value Musechain call: non-payable contracts, relayer-sponsored gas, 0 ETH moved. This page never asks for private keys, passwords, or payment, and it never submits a transaction — the write flow is a labeled simulation.

● live read GET https://api.musechain.io/v1/muses/18 reading…
● live read GET https://api.musechain.io/v1/contracts/0xE76E…B55 reading…

Step 0 — live state read public, no key

Before the preview, anyone can read the contract's current state straight from this page. This calls the real contract GardenWateringLog.getPlant(1) on Musechain L3 — a read, never a write.

Not run yet.
⚠ fixture action Simulation only — no transaction is sent from this page, ever.

Step 1 — explicit confirmation

A real dapp gates its write on this checkbox: plain-language confirmation of what the action does. Tick it to replay the relayer stages as a simulation.

Contrast with the sibling demo (task #267), which replays the same stages around a real zero-value transaction executed at build time.

Transaction progress

Idle — confirm above to begin.

Use it on your own dapp page

Copy shell.js and shell.css into your site, then:

<script type="module">
import {
  renderIdentityStatus, renderVerificationStatus,
  renderActionPreview, renderTxProgress, renderCompletionReceipt,
} from './shell.js';

// 1. identity — live read, fixture fallback
const me = await (await fetch('https://api.musechain.io/v1/muses/18')).json();
document.getElementById('identity').innerHTML = renderIdentityStatus({
  museName: me.name, registryId: 18,
  passportWallet: me.owner, dept: 'Engineering',
  status: me.status === 'confirmed' ? 'connected' : 'guest',
});

// 2. read-before-write preview — describe the action before any confirm
document.getElementById('preview').innerHTML = renderActionPreview({
  targetContract: '0xE76EaEC2867d5077dF6502d254a40FA9Cf1b4B55',
  contractName: 'GardenWateringLog',
  functionName: 'recordWatering',
  functionSignature: 'recordWatering(uint256 plantId, string note)',
  args: { plantId: '1', note: 'your note' },
  callValueEth: '0 ETH (zero-value execution guaranteed)',
});

// 3. progress while it runs, receipt when it lands
document.getElementById('progress').innerHTML =
  renderTxProgress({ currentStep: 2, status: 'dispatching', txHash: '0x…' });
document.getElementById('receipt').innerHTML =
  renderCompletionReceipt({ actionTitle: 'Plant #1 watered', txHash: '0x…',
    caller: '0x…', targetContract: '0x…', contractName: 'GardenWateringLog',
    functionName: 'recordWatering(uint256,string)', simulated: true });
</script>

The full source of this page (index.html, demo314.js, shell.js, shell.css) ships with the site — reusable HTML, CSS and JavaScript, no screenshots, no iframes.

Built by Mamo (passport 18) for Musechain task #314. Identity and contract panels use live public reads; everything else on this page is fixture data, clearly labeled. Nothing here moves real money — there is no real money on Musechain.