Chapter 08 · Builder and stacks
Builder and stacks
Designing a block stack off-chain, share links, storage and the hand-off to Launch.
The Builder is a canvas for designing a block configuration before launching. It never writes to the chain. A design is a "stack": a name plus a BlockConfig. Stacks live in the browser's local storage and in share links, and the Launch flow picks one up as its step 2.
What a stack is
type Stack = { name: string; cfg: BlockConfig };
BlockConfig is the same shape the contract takes (mask, bps, blocks, seconds, raw quote units). The Builder edits it in UI units (percent, blocks, hours, whole USDC or cirBTC) through a set of parameter specs and snaps every value to the slider's step and the contract's hard range. Storage stays in contract units so the same validate() and normalize() from the Launch flow apply. The one quote-dependent field, potMinBuy, is shown in the quote chosen in Launch step 1 and stored raw (6 decimals for USDC, 8 for cirBTC).
Share links
encodeStack serialises a stack to a short JSON object with one-letter keys and base64url-encodes it:
| Key | Field |
|---|---|
n | name |
m | mask |
w | snipeWindowBlocks |
b | snipeMaxBuyBps |
t | snipeTaxBps |
bu | burnBps |
p | potBps |
pn | potN |
mb | potMinBuy (decimal string, raw quote units) |
h | haltMaxStaleness |
The link is /launch?stack=<base64url> or /builder?stack=<base64url>. decodeStack tolerates garbage: unknown keys are dropped, unknown mask bits are cleared, out-of-range values are clamped by coerceConfig, and a block that is on but has a zero field gets the default restored. A link can therefore only ever produce a config that passes validation, or nothing.
Local storage
The Builder saves the current stack under hookarc.stack.v1. Launch reads it on mount when no ?stack= parameter is present. Clearing site data resets the design; nothing is stored server-side.
The workbench
The same BlockWorkbench component renders in two modes:
- Full (
/builder): a palette of the four blocks, a chassis showing the execution order (Halt Guard, Anti-Snipe, pot, then Auto Burn after the swap), a swap-flow view that traces one buy through the active blocks, and an inspector with sliders per parameter. - Compact (Launch step 2): the same state without the palette copy, so the launcher tunes and moves on.
Both show derived figures: the nominal buy drag in basis points (80 plus the pot share, plus the snipe tax while the window is open), a gas estimate per block, and warnings such as a snipe tax at its 50 % ceiling, a pot that fills too slowly for its N, or an Anti-Snipe window that lasts only a few seconds at Arc's block time.
Hand-off to Launch
Launch step 2 shows the loaded stack's name and a link back to the Builder with the current config encoded, so edits round-trip. On deploy, the config is normalised (fields of disabled blocks zeroed) and sent to launchWithBlocks, or to launch when the mask is zero.
web/lib/builder.tsblock metadata, parameter specs, snapping, drag and gas estimates, warningsweb/lib/stack.tsencodeStack, decodeStack, coerceConfig, localStorageweb/components/builder/BlockWorkbench.tsxthe shared canvasweb/lib/stack.test.tsround-trips and garbage tolerance