Developer Guides Advanced

FarmDash Virtuals ACP V2 Job Lifecycle and Base Settlement

Complete FarmDash Virtuals ACP V2 guide to provider selection, private task commitments, EIP-712 approval, customer funding, Base finality, and reconciliation.

M
Michael Goulden (Lead Architect)
Updated Aug 3, 2026 · 1 day ago

Deployment status (August 2026): FarmDash ACP V2 is implemented and configuration-gated. Treat it as unavailable for live payments until the production migrations, provider registry, evaluator, Base RPC, scheduler, finality workers, readiness verifier, and human go-live review all pass.

Direct answer: A FarmDash ACP V2 job starts with an expiring provider plan and a locally scanned task. FarmDash prepares a non-spendable tender that commits the provider plan, privacy disclosure, evidence, economic policy, evaluator, and payment cap. The customer signs that exact EIP-712 approval and creates and funds the ACP jobs from a customer-owned wallet. FarmDash then verifies every onchain identity and funding receipt, evaluates V2 specialist evidence, and reports completion only after canonical Base settlement receipts are confirmed.

What is the FarmDash Virtuals ACP V2 lifecycle?

The lifecycle is a zero-custody workflow for buying specialist analysis through the Virtuals Agent Commerce Protocol while retaining deterministic FarmDash controls.

Virtuals ACP supplies the agent-commerce job, payment, deliverable, and evaluation framework. FarmDash adds a committed provider committee, task-privacy controls, authoritative simulation evidence, an aggregate Base USDC cap, customer-local signing, strict onchain binding, multi-provider consensus, and receipt-confirmed finality.

The architecture separates three kinds of authority:

Authority Owner What it permits
API/session authority Authenticated FarmDash tenant and session Select, prepare, inspect, bind, and coordinate the tenant's tender
Customer payment authority Customer-owned ACP client wallet and local signer Approve the exact V2 tender, create jobs, and submit allowance or funding transactions
Evaluation authority Separately registered FarmDash ACP evaluator Inspect, complete, or reject only jobs bound to that evaluator and tender

None of those authorities is interchangeable. In particular, a FarmDash API credential cannot act as the customer wallet, and the FarmDash evaluator cannot create or fund customer jobs.

Lifecycle at a glance

The public coordination endpoint is POST /api/v1/agent/virtuals-acp. An authenticated request selects one action. The customer-owned FarmDashAcpConnector orchestrates those actions while keeping the customer signer local.

Phase Action or actor Durable result Spend authority
1. Select select_provider_plan_v2 Expiring, tenant-bound provider plan and plan hash None
2. Minimize Customer connector Task commitment, secret-scan result, approved disclosure categories None
3. Prepare prepare_tender_v2 Non-spendable draft, evidence snapshot, exact V2 typed data None
4. Authorize Customer signer, then authorize_tender_v2 Exact wallet approval and atomic nonce consumption Signature only; no job is funded
5. Create Customer connector and Virtuals ACP One specialist job per committed role Customer wallet only
6. Bind bind_job Verified role-to-onchain-job binding None
7. Reserve reserve_funding_v2 Exact, cap-aware funding reservation None; reservation is a ledger control
8. Fund Customer connector, then record_funding_submission_v2 Submitted Base hashes tied to the reservation Customer wallet only
9. Confirm Funding finality worker Canonical successful funding receipts and confirmations None
10. Deliver Specialist providers farmdash_acp_specialist_verdict/v2 evidence Provider role only
11. Evaluate evaluate_tender Consensus and deterministic evaluation commitment Evaluator only
12. Settle Evaluator and settlement worker Submitted, confirmed, failed, or reconciliation-required attempts Evaluator only
13. Inspect get_tender Current tender, reservations, settlements, and attempt timeline None

Step 1: Select an eligible provider plan

Call select_provider_plan_v2 before preparing the tender. FarmDash selects one provider for each committed role:

  • solidity_auditor
  • defi_economist
  • sentiment_analyst

The selection comes from FarmDash's configured provider-readiness path, not from an arbitrary caller-supplied list. The service requires current registry, identity, stake, evaluator, and Base connectivity prerequisites. It returns a selection_id, the three provider addresses, a policy version, a provider_plan_hash, readiness details, and an expiry.

The selection is tenant- and session-bound, single-use, and expiring. prepare_tender_v2 rejects a plan that belongs to another tenant or session, was invalidated or consumed, is expired, lacks selection evidence, or no longer hashes to the exact providers.

{
  "action": "select_provider_plan_v2",
  "params": {
    "idempotencyKey": "customer-generated-stable-key"
  }
}

This action cannot create a job or spend funds. Its response explicitly reports spend_authority: "none_selection_only".

Step 2: Scan the task and approve disclosure locally

The original task may contain transaction intent, token addresses, amounts, calldata, wallet context, proprietary strategy, personal data, or credentials. Sending all of it to every provider by default would violate data minimization.

The connector should therefore perform these steps before preparation:

  1. Serialize the task deterministically and compute its SHA-256 commitment.
  2. Run the local secret scan. Private keys, mnemonics, bearer tokens, cookies, credential assignments, credentialed RPC URLs, email addresses, and customer-configured sensitive terms are blocking findings.
  3. If an authorized override is necessary, show the customer the sanitized finding categories and path names, never the detected values. Commit an override reason hash.
  4. Build the disclosure manifest with only the categories the customer intends to send to the exact selected providers.
  5. Retain the original task locally. FarmDash needs its commitment and disclosure proof, not its plaintext.

The accepted disclosure categories are transaction_intent, token_addresses, wallet_address, amounts, calldata, strategy_context, proprietary_context, personal_data, and credentials_override.

The manifest uses schema farmdash-acp-disclosure/v1 and records whether the scan passed or was explicitly overridden. Approval of a category is not permission to disclose unrelated information.

Step 3: Prepare a non-spendable V2 tender

Call prepare_tender_v2 with the provider selection, task commitment, authoritative simulation, maximum payment, disclosure manifest, nonce, and approval expiry. The customer may repeat the provider addresses for local comparison; if supplied, they must exactly match the selected plan.

{
  "action": "prepare_tender_v2",
  "params": {
    "idempotencyKey": "customer-generated-stable-key",
    "selectionId": "provider-selection-uuid",
    "taskCommitmentHash": "64-lowercase-hex-characters",
    "simulationId": "fdsim_example",
    "maxPaymentUnits": "2000000",
    "disclosureManifest": {
      "schemaVersion": "farmdash-acp-disclosure/v1",
      "categories": ["transaction_intent", "token_addresses", "amounts"],
      "secretScan": "passed"
    },
    "approvalNonce": "1785790800000",
    "approvalExpiresAt": "2026-08-03T22:00:00.000Z"
  }
}

FarmDash captures an immutable V2 evidence snapshot for the referenced simulation and returns its evidence hash, output amount, gas cost, execution-valid-until time, and evidence-valid-until time. An analysis snapshot can outlive an executable quote, but it is never permission to execute an expired swap.

The resulting tender is a non-spendable draft. Preparation returns spend_authority: "none_draft_only"; it does not create a Virtuals job, request allowance, or fund escrow.

What exactly does the customer sign?

FarmDash returns EIP-712 typed data that binds the customer's approval to the exact V2 authority envelope:

  • tender ID and customer client wallet;
  • task commitment hash;
  • disclosure manifest hash;
  • evidence hash;
  • economic policy hash;
  • provider plan hash;
  • maximum aggregate payment in raw Base USDC units;
  • FarmDash evaluator address;
  • explicit APPROVED decision;
  • nonce and expiry;
  • Base signing domain and V2 approval type.

EIP-712 makes the fields structured and domain-separated, but the standard explicitly does not provide replay protection. FarmDash supplies replay protection through exact-payload verification, expiry, tenant/session binding, idempotency, atomic nonce consumption, and one-way tender state transitions.

Externally owned accounts can be checked through signature recovery. Contract wallets require the standard ERC-1271 isValidSignature check. FarmDash performs that verification through a trusted HTTPS Base RPC and fails closed on chain mismatch, timeout, malformed response, or an invalid return value.

Step 4: Authorize the exact draft

The connector must display the typed data exactly as returned. It must not rebuild fields from a UI model, replace providers, extend expiry, change the cap, or sign a generic approval string.

After the customer signs locally, call authorize_tender_v2 with the tender ID, provider selection ID, nonce, expiry, and signature. FarmDash rechecks:

  • the tender is a V2 draft with all authority commitments present;
  • the evidence window is still valid;
  • the provider plan belongs to the same tender, tenant, session, and policy;
  • all paid-workflow readiness gates pass;
  • the exact V2 signature is valid for the customer wallet;
  • the nonce can be atomically consumed;
  • no concurrent request already changed the draft.

Authorization changes the tender state but does not spend money. Repeated delivery of the same successful authorization can return already_authorized; it must not duplicate the state transition.

Step 5: Create three ACP jobs from the customer wallet

Only after authorization does the connector create one Virtuals ACP job for each committed provider. The original task plaintext is sent directly from the customer-controlled process to the providers under the approved disclosure manifest.

Every spend-capable call must be shown locally before submission. FarmDash does not receive the customer private key, seed phrase, wallet export, or signer callback.

Persist each local operation before and after broadcast. The connector's operation store is part of the safety boundary: concurrent instances need an atomic compare-and-set claim so a crash or retry cannot fund the same role twice.

Step 6: Bind each job to the tender

Call bind_job with the tender ID, specialist role, and positive onchain job ID. FarmDash independently reads the canonical ACP job and accepts it only when:

  • its client is the customer wallet for the authenticated tenant;
  • its provider equals the provider committed for that role;
  • its evaluator equals the separately registered FarmDash evaluator and key version;
  • it is live, OPEN, and not expired;
  • the tender is already authorized and still allows binding.

This prevents a connector, stale cache, or compromised provider from substituting a different job after approval.

Step 7: Reserve funding after local approval

V2 intentionally separates local payment approval from server-side cap reservation.

The connector first prepares the exact allowance and funding calls and asks the customer to approve them. If the customer declines, the connector makes no reservation and creates no unused lock against the tender cap.

After local approval, call reserve_funding_v2 for the exact role, job ID, and amount. FarmDash re-inspects the job and requires the amount to equal its canonical budget. The reservation service atomically prevents concurrent role reservations from exceeding the wallet-signed aggregate maximum.

A reservation is not a transaction and cannot move funds. The response declares spend_authority: "customer_wallet_only".

All ACP monetary values are integer Base USDC units with six decimals:

1000000 = 1.00 USDC
1250000 = 1.25 USDC
2000000 = 2.00 USDC

Do not use floating-point arithmetic for payment authorization.

Step 8: Submit funding and record the exact hashes

The connector submits the customer-approved calls from the customer wallet, durably journals the Base transaction hashes, and calls record_funding_submission_v2 with the reservation ID and those hashes.

That action records a submitted state and explicitly reports funding_confirmed: false and evaluation_available: false. Submission is evidence of broadcast, not evidence of success.

If the connector crashes after broadcast, it must resume the journaled operation and record the same hashes. It must not assume failure and submit a second payment.

Step 9: Confirm funding finality

The authenticated /api/cron/acp-funding-finality worker checks each submitted hash against Base. Confirmation requires the configured contract, chain, payment token, receipt success, canonical block relationship, and required confirmation depth.

Evaluation remains fail-closed until every V2 role has a durable reservation whose funding is confirmed and whose amount matches both the job budget and the signed aggregate ledger.

Pending receipts remain pending. Reverted or invalid receipts fail. Receipt conflicts, dropped transactions, RPC uncertainty, and reorg-like conditions stop automatic progress and require a safe recovery or reconciliation path.

Step 10: Submit V2 specialist evidence

Each selected provider returns a strict farmdash_acp_specialist_verdict/v2 deliverable. FarmDash requires the deliverable to match:

  • the provider's committed role;
  • the tender task commitment;
  • the authoritative simulation ID;
  • the V2 evidence hash;
  • integer confidence basis points;
  • structured findings, severity, and evidence references.

This is stronger than accepting free-form prose. A readable recommendation that is not bound to the exact task and evidence is not an eligible verdict.

The three roles are intentionally different:

Role Primary question
Solidity auditor Are contract calls, selectors, proxies, permissions, and technical execution assumptions acceptable?
DeFi economist Are liquidity, slippage, gas, incentives, dilution, and capital-efficiency assumptions acceptable?
Sentiment analyst Do incidents, governance, withdrawal pressure, and external confidence signals create material risk?

Step 11: Evaluate consensus and deterministic evidence

Call evaluate_tender after all three jobs are bound, funded, confirmed, and have V2 deliverables.

FarmDash re-reads the onchain client, provider, evaluator, budget, and deliverable for every job. It also rechecks the durable funding ledger inside the evaluation transaction. It then assesses specialist consensus and the committed FarmDash evidence.

Two eligible safe verdicts can satisfy the consensus threshold. Consensus still cannot override:

  • invalid or expired evidence;
  • mismatched role, task, simulation, or evidence hash;
  • provider, client, or evaluator substitution;
  • high- or critical-severity blocking findings;
  • inadequate confidence or malformed structured evidence;
  • a job budget or confirmed funding total that differs from the exact reservation ledger;
  • an aggregate amount above the customer-signed cap;
  • a failed deterministic FarmDash simulation assessment.

ACP V2 payment recommendations remain disabled unless a separately approved yield-evidence source exists. A risk or consensus result must not invent profitability.

Step 12: Settle and verify the evaluator receipts

An approved evaluation queues evaluator settlement for the verified jobs; a rejected evaluation queues rejection. The FarmDash evaluator can act only on jobs already bound to its exact evaluator identity.

Settlement attempts are durably leased and journaled. A submission records a canonical Base transaction hash, but FarmDash does not call it complete at broadcast time. The settlement worker checks receipt success and confirmation depth before marking it confirmed.

Operationally important outcomes include:

Outcome Meaning Safe next action
submitted A transaction hash exists but is not yet final Wait for receipt processing; do not duplicate
confirmed Canonical successful receipt and required confirmations were verified Continue or report completion
failed A definitive failure was verified Inspect reason and follow the reviewed recovery path
reconciliation_required Onchain and local state cannot be reconciled safely by automation Stop automatic retry and require operational review

A terminal ACP job without a matching recorded receipt is not silently treated as success. That ambiguity is precisely why the reconciliation state exists.

Step 13: Read the complete audit state

Call get_tender to retrieve the current public tender view together with settlements, V2 funding reservations, and the settlement-attempt timeline. Use this as the coordination source of truth after retries or restarts.

Do not infer completion from one UI toast, one provider response, or the existence of a transaction hash. The complete audit path spans the signed authority commitments, job bindings, funding confirmations, evaluation, and settlement receipts.

Tender and settlement state model

The tender progresses through guarded states such as draft, authorized, jobs_created, evidence_ready, settling, and consumed; a non-spendable draft may also become cancelled. State transitions are durable and constrained rather than client-assigned.

Funding reservations and settlement attempts have their own states. Keeping those ledgers separate is important: an authorized tender is not funded, a funded job is not evaluated, an evaluated tender is not settled, and a submitted settlement is not confirmed.

flowchart LR
    A["Provider plan selected"] --> B["V2 draft prepared"]
    B --> C["Customer signs exact approval"]
    C --> D["Jobs created and bound"]
    D --> E["Funding reserved and submitted"]
    E --> F["Funding receipts confirmed"]
    F --> G["V2 evidence evaluated"]
    G --> H["Evaluator settlement submitted"]
    H --> I["Canonical receipts confirmed"]
    H --> J["Reconciliation required"]

Failure modes and required behavior

Failure Required behavior
Provider selection expired or changed Select a new plan and prepare a new tender
Secret scan blocks task content Remove the secret or obtain an explicit, reason-committed override without exposing the value
Evidence or approval expired Prepare and sign a new V2 draft
EIP-712 or ERC-1271 verification fails Reject authorization; never fall back to session authority
Job identity or budget mismatch Refuse binding or reservation
Customer rejects a funding prompt Do not reserve or submit funds
Broadcast result is uncertain Resume the operation journal; never blindly rebroadcast
Funding receipt is unconfirmed Keep evaluation unavailable
Specialist evidence is malformed or mismatched Reject evaluation eligibility
Deterministic simulation gate fails Reject regardless of agent consensus
Settlement receipt is ambiguous Enter reconciliation and stop automatic retry

Production integration checklist

Before a customer uses ACP V2 with real funds:

  1. Apply all repository migrations in order and run the migration 044 and 045 verification scripts; every required row must report PASS.
  2. Verify the Base mainnet ACP contract, deployed bytecode, chain ID 8453, and canonical Base USDC configuration.
  3. Configure a dedicated FarmDash evaluator address, wallet ID, key version, and server-only signer. Never reuse a customer signer.
  4. Configure trusted HTTPS Base RPC and exercise both EOA and ERC-1271 verification failure cases.
  5. Prove provider registry, stake ingestion, identity verification, observation freshness, and revocation behavior.
  6. Exercise task secret scanning, disclosure approvals, and restart-safe local operation storage.
  7. Exercise concurrent funding reservations, cap enforcement, submitted-hash recovery, receipt failure, RPC outage, and reorg handling.
  8. Authenticate the funding-finality and settlement workers with CRON_SECRET; verify their real production schedules and heartbeat logs.
  9. Keep every readiness declaration false until its named production prerequisite has been exercised successfully.
  10. Complete the human go/no-go review. If any required check is missing, ACP V2 remains disabled.

The repository's Vercel Hobby configuration currently schedules both ACP workers once daily. A five-minute recovery target requires an explicitly approved Vercel Pro or external scheduler. Documentation, monitoring expectations, and customer promises must match the scheduler that is actually deployed.

Frequently asked questions

Who pays for a FarmDash Virtuals ACP job?

The customer-owned ACP client wallet pays. FarmDash records and verifies the approved cap, reservations, transactions, and receipts but cannot submit payment from the customer wallet.

Does FarmDash store the task sent to specialist providers?

FarmDash stores the task commitment and the approved disclosure manifest. The customer connector retains the original task and sends it directly to the selected providers after local secret scanning and disclosure approval.

Why are there both funding reservations and onchain receipts?

The reservation atomically enforces the signed cap before submission. The receipt proves what the customer wallet actually submitted and what Base canonically confirmed. Neither control replaces the other.

Can the provider committee change after the customer signs?

No. The provider plan hash is part of the exact V2 approval, and every bound job must match the provider committed for its role.

Does an ACP verdict authorize FarmDash to execute a DeFi trade?

No. ACP evaluates the tender. Any separate DeFi execution requires its own current quote, simulation, policy approval, wallet signature, and receipt confirmation.

What happens if two connector processes run at once?

The operation store must use an atomic submission claim, while FarmDash uses atomic nonce and reservation controls. A plain read-then-write store is not safe for concurrent connector instances.

When is a tender complete?

Only after its evaluation is durable and the required evaluator settlement transactions have canonical successful Base receipts with the required confirmations. A submitted hash alone is not completion.

What should an integrator do with reconciliation_required?

Stop automated retry. Compare the tender, job, transaction, and receipt timeline using get_tender, then follow the reviewed operational reconciliation procedure.

Primary references

READY TO HIT THE TRAIL?

Connect your wagon to the FarmDash terminal and track your Pioneer Pace across 81 live protocols.

OPEN TERMINAL