What you will learn
By the end of this workflow, you will have seen how:- authored agreement JSON defines variables, participants, states, inputs, issuers, and transitions
- deployment context supplies live values such as participant wallets,
chainId, and initialization data - deployment preflight normalizes the values that must be signed
- EIP-712 permits authorize deployment and input submission
- submitted inputs move an agreement through its authored state machine
- state and input history provide receipts for what happened
Before you start
This tutorial has two equivalent paths. Use the MCP path when an agent is operating Shodai through MCP tools. Use the SDK path when you are building the workflow into a TypeScript integration.
For setup details, see Quickstart with TypeScript SDK, Quickstart with MCP, TypeScript client reference, Authentication, and Complex Agreement.
Use testnet for a first run. Deployment and input submission are writes. They require signatures from eligible wallets, and successful submissions are not safe to retry blindly.
Run this workflow with an agent
Run this workflow with an agent
Choose a path
Both paths use the same lifecycle and the same underlying API model. The difference is the surface you operate through.Run the workflow
- MCP
- SDK
1
Load the service retainer example
Read the MCP resources return JSON as text. Parse the returned
complex-example-agreement MCP resource.The resource URI is:contents[0].text value and keep the parsed object as agreement for the remaining MCP tool calls.This is the same agreement documented in Complex Agreement. It starts in AWAITING_PAYMENT, moves to WORK_IN_PROGRESS after initial payment proof, supports invoice review paths, can branch into top-up review, and can terminate through a final invoice flow.2
Validate the authored agreement JSON
Call
validate_agreement with environment: "testnet" and pass the parsed complex-example-agreement object as agreement.Review the validation result before continuing. The important evidence is the participant variable keys, state IDs, input IDs, and warnings. For this example, expect participant-backed variables such as serviceProviderRepresentative and clientRepresentative, and lifecycle inputs such as submitInitialPaymentProof and submitInvoice.Structural validation checks the agreement artifact only. It does not know which wallets or initialization values you will use for deployment.3
Prepare deployment values
Choose deployment context for the first run.
Keep participant wallet mappings and initialization values stable after preflight. If they change, regenerate the deployment typed data before signing.
4
Preflight deployment
Call Review the returned variables, participants, observers, contributors, and warnings before any signing step.
preflight_deployment with the loaded agreement object, target chain, initialization values, and participant mappings.Use this deployment context with the loaded agreement:Preflight does not deploy the agreement. It assembles and validates the deployment request so you can sign the effective values rather than raw caller input.
5
Sign and deploy
For hosted MCP with external signing, call Pass the same
prepare_deployment_typed_data, sign the returned EIP-712 payload, then call deploy_agreement with the returned document link, normalized values, and permit fields.Call prepare_deployment_typed_data with:environment:"testnet"agreement: the loadedcomplex-example-agreementobjectchainId:59141signerAddress: the wallet address that will sign and own the deploymentinitValues: the same values used for preflightparticipants: the same participant mappings used for preflight
agreement, displayName, and chainId; the returned docUri and documentId when present; the normalizedInitValues, normalizedParticipants, and normalizedObservers returned by prepare_deployment_typed_data; and signer address, deadline, and signature fields into deploy_agreement.6
Read the deployed state
After deployment, call The service retainer starts at
get_agreement_state.AWAITING_PAYMENT. The current state tells you which authored inputs can move the lifecycle next.7
Submit the first lifecycle input
Submit Sign the returned EIP-712 typed data externally, then call
submitInitialPaymentProof to move the retainer from AWAITING_PAYMENT to WORK_IN_PROGRESS.First call prepare_input_typed_data with an eligible signer and the input values.submit_input with the same agreementId, inputId, values, signer address, deadline, and signature fields.The submitInitialPaymentProof input can be issued by either representative in the service retainer example. Later inputs may be restricted to one role.8
Inspect state and history
Reread current state and input history.Use state to confirm the lifecycle position and input history to confirm that the submitted input appears with its status. Depending on transaction timing, an input may be
PENDING, FINALIZED, or FAILED.Try a branch
After the agreement reachesWORK_IN_PROGRESS, try one additional path to see why the complex example is useful.
Submit an invoice without a top-up request
Submit an invoice without a top-up request
Submit the This path moves the agreement to
submitInvoice input from WORK_IN_PROGRESS. The service provider representative must sign this input.Required values:INVOICE_SUBMITTED. From there, an authorized representative can approve, reject with feedback, or initiate termination.Submit an invoice with a top-up request
Submit an invoice with a top-up request
Submit the This path moves the agreement to
submitInvoiceWithTopup input from WORK_IN_PROGRESS. The service provider representative must sign this input.Required values:INVOICE_SUBMITTED_WITH_TOPUP. The next step can approve with payment proof, reject with feedback, or initiate termination.What happened under the hood
This tutorial uses one concrete agreement to exercise the core Shodai model.If a step fails
Use Errors and troubleshooting for API errors, signing failures, and lifecycle diagnostics. Before retrying a write, reread state and input history so you do not sign or submit against a stale lifecycle position.Next steps
Inspect the complex agreement
Study the complete service retainer JSON, lifecycle diagram, states, inputs, and transitions.
Author your own agreement
Turn a business workflow into agreement JSON after you have run the lifecycle once.
Build with the SDK
Use the TypeScript client reference for typed API calls, signing helpers, and diagnostics.
Quickstart with MCP
Configure the hosted MCP server and operate agreements through MCP tools.