Arete documentation
Add a deadline and test the lifecycle
For the complete documentation index optimized for AI agents, see llms.txt or llms-full.txt. A markdown version of this page is available by appending.mdto the URL or sendingAccept: text/markdown.
For AI agents: the documentation index is at llms.txt (full corpus: llms-full.txt). A markdown source for this page is /building-protocols/tutorial-lifecycle.md.
Extend your first protocol to give each instance a deadline. You will test role rejection, successful closure, and expiration, then connect the same state and actions to an application.
This remains a teaching example using transfers between wallets. Expiration closes the Arete workflow; it does not recover money from the recipient.
1. Declare the deadline
Section titled “1. Declare the deadline”In protocol.ts, change params to:
params: { amount: "u64", deadline: "unixTimestamp" },Add deadline to the open step’s arguments and check that it is in the future:
args: { recipient: "pubkey", amount: "u64", deadline: "unixTimestamp" },guards: { amount_zero: "args.amount > 0", deadline_not_future: "args.deadline > now",},Creation retains the deadline as an instance parameter. Replace
machines.instance with:
instance: { initial: "open", states: { open: "recorded", closed: { kind: "recorded", terminal: true }, expired: { kind: "derived", terminal: true }, }, derive: [{ from: ["open"], to: "expired", when: "now >= params.deadline", at: "params.deadline", }],},Keep the close step’s existing authority, guards, transition, and transfer.
Add a guard so preparation also checks the deadline immediately:
deadline_passed: "now < params.deadline",The derived state makes expiry visible even without someone calling close.
The guard checks the boundary when the step is prepared.
2. Check and deploy into the fork
Section titled “2. Check and deploy into the fork”npx arete-protocol checka4 dev up --openIf a4 dev up is already watching, save the file and wait for the new
deployment to become active instead of starting a second session. Use
a4 dev status to inspect the environment’s clock. Choose a Unix timestamp
in seconds at least an hour ahead of that clock, and use its decimal string
as <deadline> below.
3. Test the successful path
Section titled “3. Test the successful path”Create or inspect creator and recipient with a4 dev wallet <name>.
Open a fresh instance:
a4 dev step open --wallet creator --args '{"recipient":"<recipient-pubkey>","amount":"1000000","deadline":"<deadline>"}'With the returned id, try close as creator and expect rejection, then close
as recipient:
a4 dev step close --wallet creator --instance <instance-id> --args '{"amount":"1000000"}'a4 dev step close --wallet recipient --instance <instance-id> --args '{"amount":"1000000"}'a4 dev instance <instance-id> --wallet recipientThe first command exits non-zero by design. The second completes, and the
instance becomes closed. A repeat is rejected with instance_terminal.
Follow a4 stream --dev --instance <instance-id> to inspect activity.
4. Test expiration
Section titled “4. Test expiration”Open another instance with the same future deadline and copy its id. Advance the environment past that deadline:
a4 dev warp +2ha4 dev instance <second-instance-id> --wallet recipienta4 protocol actions --dev --wallet recipient --instance <second-instance-id>Use a larger warp if your deadline was more than two hours away. The time
transition is processed asynchronously; re-read until the instance is
expired. Its steps then report instance_terminal. A prepare at the time
boundary can instead reject with deadline_passed before the derived state
has been recorded. Your UI should handle both outcomes.
Changing the fork’s clock affects every protocol in that environment. Use a separate environment when another experiment needs its original clock.
5. Build the interface
Section titled “5. Build the interface”Use the generated dev client from the local
build. Display the instance state with useProtocolInstance, and use
useAllowedSteps with the connected wallet to explain why closure is unavailable.
Keep preparation’s rejection handling even when a button was enabled.
The same view should show three meaningful outcomes: open and actionable for the recipient, closed after confirmation, or expired after the deadline. See the React guide for the hooks and execution guide for signing and submission.
For repeatable tests, save checkpoints before changing chain state and use step replay. Recompute deadlines when replaying after the environment clock has advanced.