02 - First Movement (Dry-Run)
Experience the full flow in dry-run mode: register a template -> create a movement -> approve it -> check status. Confirm behavior through the API layer only, without live exchange integration.Prerequisite: In 01-local-setup.md, the server is running on
localhost:8100 with MG_AUTH_ENABLED=false and MG_WORKERS_ENABLED=false.
Full Flow
Step 1: Register a Template
Register a CEX 3-node template (Upbit -> Bybit XRP):Check these fields in the success response:risk_controlsis free-form, and onlymax_amountbinds.max_amountis enforced fail-closed at dispatch.asset_allowlistis descriptive — it is pinned into the plan hash, but nothing rejects a movement whoseintent.assetfalls outside it. See the v3 endpoints reference for the full enforced set.
graph_shape:"linear"- executable in v3.0executable_in_v3_0:truetopological_order:["withdraw", "withdraw_observe", "deposit_observe"]
Step 2: Create a Movement
Create a movement from the registered template:movement_id: UUID - used in later API callsrequest_state:"PENDING_APPROVAL"- waiting for approvalcompiled_plan_hash:"sha256:..."- required for approval
You can create a movement withoutcallback. It still works, but no state-change notifications are sent. The callback URL is a nested field —callback: {"url": "..."}, not a top-levelcallback_url(a top-levelcallback_urlis silently ignored).
Step 3: Approve the Movement
Send the approval request withcompiled_plan_hash:
request_state:"APPROVED"-> if workers are enabled, it transitions to"EXECUTING"approval_status:"approved"
Whycompiled_plan_hashis required: it guarantees the plan was not altered between creation and approval. Sending the wrong hash returns409 Conflict.
Step 4: Check Status
MG_WORKERS_ENABLED=false):
request_statestays at"APPROVED"(because the dispatcher is off)- Node state stays
"BLOCKED"(the first frontier node) or remains inactive
request_state:"EXECUTING"->"COMPLETED"- Node states advance per node kind. The representative path for a signing on-chain action node is
BLOCKED->READY->PREPARING->AWAITING_SIGNATURE->SUBMITTING->SUBMITTED->OBSERVING->COMPLETED. Common variants: a node needing no signature skipsAWAITING_SIGNATURE; a sync-terminal submit (e.g.cex_withdrawal) goesSUBMITTING->COMPLETEDdirectly; an observe-only node (e.g.cex_deposit_status) goesREADY->OBSERVING->COMPLETED.
Step 5: List Movements
Python Client Example
Movement State Flow Summary
- PENDING_APPROVAL: Waiting for approval.
POST .../approveorPOST .../reject - APPROVED: Approved. If workers are enabled, it automatically transitions to EXECUTING
- EXECUTING: Nodes are running
- COMPLETED: All nodes finished
- FAILED: An unrecoverable failure occurred
For the full state machine, see the States and Transitions reference.
Troubleshooting
Next: 03-template-cookbook.md - template examples by lane