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.