Skip to content

Page Templates

The signing and signup pages use a template/engine split: HTML/CSS is replaceable, JavaScript wallet logic stays with the engine.

Separation

template (HTML/CSS)     — layout, branding, copy, styles
engine bundle (JS)      — wallet connection, signing, chain interaction
generator (script)      — injects config variables, combines template + bundle → output

The template never contains wallet or chain logic. The bundle never contains layout or styling.

Customizing

To create a custom template:

  1. Copy the default template.html or signup-template.html from an engine
  2. Modify HTML structure, CSS, copy, images — anything visual
  3. Keep all required DOM element IDs intact
  4. Keep the CONFIG script block and engine.js include
  5. Rebuild with the generator script

Required DOM Elements

Signing page

Element IDTypePurpose
btn-connectbuttonTriggers wallet connection
btn-signbuttonTriggers message signing
wallet-addressspan/divDisplays connected wallet address
status-messagedivShows status/error messages
step-connectdivConnect wallet step container
step-signdivSign message step container

Signup page

Element IDTypePurpose
btn-connectbuttonWallet connection
btn-signbuttonMessage signing
btn-purchasebuttonSubscription purchase
wallet-addressspan/divWallet address display
plan-selectselectPlan selection
days-inputinputSubscription duration
total-costspan/divComputed cost
status-messagedivStatus/error display
step-connectdivConnect step container
step-signdivSign step container
step-purchasedivPurchase step container
step-serversdivView servers container
server-listdivDecrypted server details

CSS Classes

The engine bundle toggles these classes — the template defines what they look like:

ClassApplied toMeaning
hiddenstep containerNot yet active
activestep containerCurrently active
completedstep containerFinished
disabledbuttonNot clickable
loadingbuttonOperation in progress
errorstatus-messageError state
successstatus-messageSuccess state

CONFIG Object

The generator injects configuration as a global object:

html
<script>
  const CONFIG = {
    publicSecret: "{{PUBLIC_SECRET}}",
    serverPublicKey: "{{SERVER_PUBLIC_KEY}}",
    rpcUrl: "{{RPC_URL}}",
    nftContract: "{{NFT_CONTRACT}}",
    subscriptionContract: "{{SUBSCRIPTION_CONTRACT}}",
    // Engine-specific (present or absent):
    chainId: {{CHAIN_ID}},             // EVM only
    usdcAddress: "{{USDC_ADDRESS}}",   // EVM only
    paymentToken: "{{PAYMENT_TOKEN}}"  // OPNet only
  };
</script>
<script src="engine.js"></script>

Full Contract

See facts/PAGE_TEMPLATE_INTERFACE.md for the complete specification.