Steps and registers
How a step captures a value and how a later step pipes it back in.
A plan is a list of steps. Two mechanisms move data between them: a step can captureits callee's return value into a register, and a later step can splice a register back into its own instruction data before it runs. That is the entire piping model.
Capture
Set captureInto: non a step. After its CPI returns, PTBVM reads the callee's return data as a little-endian u64 and stores it in register n. Set capturePubkey: true instead to capture a 32-byte pubkey the callee returned, so a later step can reference it as an account.
Splice
Add a dataSplices entry to a step. Before the step runs, PTBVM overwrites width bytes of its instruction data at offset with the value in register. The default width is 8 (a u64). This is how a captured amount becomes the input to the next call.
| Field | Type | Note |
|---|---|---|
| captureInto | number | null | Store this step's u64 return value in the given register slot. |
| capturePubkey | boolean | Capture a returned 32-byte pubkey instead of a u64 value. |
| dataSplices[] | { offset, register, width } | Overwrite width bytes of this step's data at offset with a register value. width defaults to 8. |
Register file
The register file is a fixed-size array of eight u64 slots, held in a PDA owned by the caller. It lives on chain for the duration of the plan; captured values never round-trip through your client. Slots default to zero.
In this section
- The obligation gate: The hot-potato check that reverts the whole plan if an obligation is left open.
- Token-2022: Why Token-2022 composes as a plan step with no special casing.