Approve a deal with your own key

Your agent prepares the deal. You review the complete terms and approve the exact version. Your private key stays on your computer.

Download the local deal approval command · Approve an advert · Connect your agent · Start a private trial

What you can approve

This command supports direct Ed25519 party keys. Delegated authority, other legal profiles, Bitcoin and Solana approvals, card checkout approvals and payment dispatch signatures need their own supported owner-signing flow. They are not converted into this profile. The broader system retains those separate capabilities.

Get the complete deal first

Your agent can prepare an unsigned brief with the public tools. A payable marketplace order also needs the complete checkout packet from a reviewed integration. If you do not have that connection, ask for first-order setup help before running this command. Send a workflow outline, not keys or private access files. This command reviews and signs an existing supported packet; it does not construct one.

First setup

  1. Keep the private access file you downloaded from the trial page. Store it outside your agent’s workspace and chat. Never give it to another person or upload it to the service.
  2. Download the command above to your own macOS or Linux computer. Use Python 3.10 or later. Install the signing library once:
python3 -m venv ./covenant-signing
./covenant-signing/bin/python -m pip install cryptography==50.0.2

The command works offline and does not need the Covenant core package. It accepts no passwords or wallet keys. Its local terminal prompt is a consent step; software already running as you can still read your files. It does not provide hardware isolation.

Approve the exact agreement

  1. Ask your agent to save the complete bare agreement as deal.json and its exact decoded trade.signing_payload result as approval-request.json. Retain the expected agreement ID separately. Do not approve a shortened summary or a hash without the complete terms.
  2. For a marketplace successor agreement, also save the complete decoded market.prepare result as market-package.json. It includes the original advert, order, fee disclosure and full payment requests. Include --package ./market-package.json in the command.
  3. Run the command, read the terms, complete history and exact action, then type the displayed APPROVE phrase only if they match your intent:
chmod 600 ./AAP-private-trial-access.json ./deal.json ./approval-request.json
./covenant-signing/bin/python -I ./approve_trade.py \
  --access ./AAP-private-trial-access.json \
  --bundle ./deal.json --payload ./approval-request.json \
  --expected-trade YOUR_SEPARATELY_RETAINED_AGREEMENT_ID \
  --mode assent --output ./my-approval.json

For marketplace terms, make the package owner-private too and append --package ./market-package.json. Every input must belong to you, have owner-only permissions and have no symbolic or hard links. Choose a new output filename each time; existing files are never overwritten.

  1. Return only my-approval.json to your agent. For an ordinary agreement, the agent calls aap_hosted_trade_attach_assent with the unchanged bundle, expected ID and approval record. Each party retains the resulting complete bundle with aap_hosted_trade_receive, using the current checkpoint, independently checked snapshot and one retained request key.
  2. For a marketplace agreement, attach each party’s assent to a separate copy of the unchanged package bundle, then call aap_market_receive with the original package, complete signed bundle and expected agreement ID. Do not edit the package’s original bundle, fee quote or request attachments to insert later signatures. Both parties keep their own complete records.

The source order and final payment-enabled agreement have different IDs. Approving the source does not approve the successor. A fee provider’s signature covers its own fee terms; it does not approve the buyer’s spending or the seller’s work.

Check who must resolve a dispute. This native profile requires every named participant to sign a resolution. If the fee recipient joins as a third participant, its signature is also required to clear a buyer-and-seller dispute. Fee-free two-party agreements do not add that third participant.

An adapter identifier, payment request hash or owner-verifier policy always requires the complete supported market package, even if its surrounding context is renamed or described as manual. The source packet must contain ordinary manual promises; hidden automatic execution requests inside that source are refused. The command never treats a changed context label as permission to approve an opaque hash. Manual promises and barter can still describe arbitrary resources or units.

Record delivery, acceptance or a dispute

Ask your agent to call aap_hosted_trade_event_payload for the complete current bundle and save the decoded reply as update-request.json. The actor comes from the current account. The supplier claims delivery; the buyer accepts the exact current claim. Either participant can dispute. Under this direct-party profile, a resolution clears a dispute only when every participant signs the same resolution.

chmod 600 ./deal.json ./update-request.json
./covenant-signing/bin/python -I ./approve_trade.py \
  --access ./AAP-private-trial-access.json \
  --bundle ./deal.json --payload ./update-request.json \
  --expected-trade YOUR_SEPARATELY_RETAINED_AGREEMENT_ID \
  --mode event --output ./my-update-approval.json

Include the unchanged --package for a marketplace agreement. The agent attaches the returned complete event record with aap_hosted_trade_attach_event, then retains the new bundle through the matching native or market receive operation. The command refuses a changed event prefix, wrong actor, stale claim, invalid signature or missing assent. An acceptance is your statement about supplied evidence, not an independent inspection of the deliverable.

Name the receiving or payer wallet

For an original source deal using Base or Ethereum USDC, ask for aap_payment_instruction_payload with the complete source bundle, payment leg, kind and exact external wallet address. Save the decoded reply as wallet-request.json. The seller uses destination; the payer uses sender.

chmod 600 ./source-deal.json ./wallet-request.json
./covenant-signing/bin/python -I ./approve_trade.py \
  --access ./AAP-private-trial-access.json \
  --bundle ./source-deal.json --payload ./wallet-request.json \
  --expected-trade YOUR_SEPARATELY_RETAINED_SOURCE_ID \
  --mode wallet --kind destination --leg give-0 \
  --address YOUR_EXACT_EXTERNAL_WALLET_ADDRESS \
  --output ./my-wallet-instruction-approval.json

The agent submits the returned signature, unchanged source, leg, kind and address to aap_payment_register_instruction with a retained request key, then reads it back with aap_payment_get_instruction. The first instruction is immutable. A different receiving address needs a fresh source deal and fresh approvals. Principal payments never default to Covenant’s fee wallet.

Keep the same record when a call is interrupted

Read back the original trade, instruction or request before repeating a change. Retry only the identical operation with unchanged fields and its original request key. For an uncertain marketplace payment, use aap_market_review, aap_market_observe and aap_market_export; never create a replacement payment. Keep exports private.

What this review establishes

The command independently checks the supplied native terms, direct-party signatures, event sequence and roles. In a supported market package it also checks source/order bindings, signed publication, exact fee arithmetic, signed fee promises, request hashes and final terms. It displays all attached clauses and evidence references; it does not execute a legal interpreter, fetch missing evidence, verify the provider’s code or decide whether those promises are legally enforceable.

A signed launch disclosure states the quoted fee and its validity period. Its posted-policy ID remains a reference: this command does not independently establish current operator policy, account access, publication freshness, wallet control, external finality or world truth. It makes no network call and sends no money. A later wallet payment still requires its own explicit signing flow.

Developer format and checks

Signatures use Ed25519 over the ASCII domain label, one zero byte, then sorted compact canonical JSON. Only printable ASCII strings, exact booleans, null and safe JSON integers are accepted. Resource quantities are positive integer strings. Duplicate keys, floats and terminal control characters are refused. The complete reciprocal body is pinned by AAP-RECIPROCAL-TRADE-TERMS-0.1; assent and events use their separate AAP-RECIPROCAL-TRADE-ASSENT-0.1 and AAP-RECIPROCAL-TRADE-EVENT-0.1 domains. The local confirmation includes the complete reviewed history and package, while the exported signature covers only the exact protocol action.

The client accepts a bare payload or its exact supported native/HTTP receipt; save decoded tool values, not raw JSON-RPC wrappers. Market package input is the bare complete market.prepare result. Native TradeBundle inputs have exactly body, id, assents, events. Public-key admission follows the public decoding rules in RFC 8032; signing and signature verification use the cryptography library.