ERC-8313: Protocol Interaction Manifest

The Problem

Protocol interaction knowledge exists primarily in websites and SDKs and not on-chain or in a portable machine-readable format. The websites set up to support dApps are a centralisation risk that depend upon developer team availability for regular maintenance.

Every DeFi protocol exposes functionality through smart contract ABIs. While an ABI can tell you the function names, parameter types and returned values, it does not tell you anything about how to use them.

The more complex protocols, such as UniSwap and ENS, are a system of smart contracts where one contract may be used to discover details while a different contract is used to complete an action. To use these protocols, a user must either connect their wallet to a dApp’s webpage or write code using an SDK.

As more protocols are introduced, the ability to maintain wallets supporting these protocols becomes more difficult. Every new protocol would require a new integration. Any update to a protocol would require updating code. Supporting 50 protocols means maintaining 50 integrations where none of the logic is portable, auditable, or shareable.

As an example, if an autonomous agent is instructed to “lend 500 USDC on Aave”, it would have to determine that it must call getReserveData first, check the health factor, approve an allowance for the pool contract, call supply with the right referral code, and then confirm that the aToken balance has increased. That knowledge is currently not available in a form that a generic agent can read.

This problem becomes even more significant for generic wallet software, automation systems, and autonomous agents which cannot rely on bespoke integrations for every protocol.

The Solution

A Protocol Interaction Manifest (PIM) is a structured, machine-readable JSON document that describes how to interact with a smart contract protocol. It is not just a list of available functions but the full workflow required to safely and correctly fulfil a user’s intent.

A PIM answers three questions that an ABI cannot:

  • What does the user want to achieve? (intent layer)

  • What on-chain data needs to be gathered first? (lookup layer)

  • What transactions need to be build, in what order, with what safety checks? (execution layer)

A wallet or autonomous agent that understands the PIM execution model can load a manifest for any protocol it has never seen before and immediately know how to build a correct, safe transaction on behalf of the user — without any hardcoded protocol knowledge.

This would be a mechanism that translates intent into transactions.

It would be important to note that this does not replace ABIs but instead would augment them. It would be an optional metadata layer describing workflow semantics and execution requirements.

Safety

While a PIM may facilitate the use of dApps, it would also present a new attack vector if not implemented carefully. Any application using them would need to follow a standard set of best practices as preventative measures. These practices would include, but are not limited to:

  • transaction simulation

  • permission boundaries

  • validation

  • risk disclosures

  • trust levels

  • transaction constraints

The PIM would also include a signature section so that it can be verified against a known public key.

Discovery

An obvious question may be how an application would discover a PIM. This is where the trust levels would be applied. There could be multiple sources for PIMs including the dApp development team, established companies providing them as a service, or private individuals filling gaps. Trust levels would be used to categorise the providers of PIMs. The application would take extra precautions for PIMs with low trust levels such as blocking certain functions or providing additional risk disclosures to the user.

There could be a number of registries for these files available on hosted websites, on-chain, or using IPFS. ENS text records or Ethereum Comment Protocol could also be used to broadcast the PIMs or at the very least broadcast the latest version along with its signature.

In Summary

A Protocol Interaction Manifest would be a structured, machine-readable specification describing how an application, wallet, or automation system can safely interact with a smart contract protocol.

This is what I have as top-level objects in the PIM. There is no safety section because if the PIM was compromised then you could not trust that section anyhow.

This maps closely to work already in progress across a few active proposals, worth making the connections explicit.

On the manifest / discovery layer: agent.json served via ENS CCIP-Read (EIP-3668) is already a deployed version of this pattern for the agent side. The PIM is the protocol-side equivalent, instead of “what can this agent do” it’s “how do you interact with this protocol.” Same discovery infrastructure, complementary documents. ENS text records pointing to an IPFS CID for the PIM, resolved via CCIP-Read, gives you off-chain storage without gas costs per update and ENS-native versioning.

On the safety gap: the “no safety section because a compromised PIM can’t be trusted” problem is exactly what WYRIWE’s sanitization_pipeline_hash addresses. If the agent pins the PIM’s IPFS CID as part of its input commitment:

sanitization_pipeline_hash = keccak256(pim_cid || raw_input_hash)


A tampered or substituted PIM produces a different hash, detectable by any verifier checking the attestation. The safety guarantee doesn’t live inside the PIM; it lives in the commitment scheme that binds which PIM was used to which execution. WYRIWE spec: https://github.com/TMerlini/wyriwe

On the execution / settlement layer: ERC-8183 and ERC-8274 cover what happens after the PIM is consumed, the agent commits to the input, executes, and the output is settled on-chain with a verifiable proof. The PIM gets the agent to the right calldata; WYRIWE + OCP + ERC-8274 prove it used the right PIM to get there.

The three questions you identified (intent / lookup / execution) map cleanly onto the trust stack: WYRIWE anchors what entered the reasoning boundary, OCP anchors it on-chain before execution runs, ERC-8274 verifies the output. The PIM is the missing upstream piece that describes the protocol interaction knowledge the agent consumed, worth a formal requires: link between the specs once this has a number.

1 Like

Additional details can be found here: https://medium.com/@paulangusbark/introducing-erc-8313-protocol-interaction-manifests-1ef8bfc63040

Following up on the requires: link I sketched above — it’s no longer hypothetical. Over in the ReceiptOS thread, TMerlini and I pinned the field mapping for a WYRIWE slice inside the receipt capsule (input_commitment.raw_input_hash + input_commitment.sanitization_pipeline_hash, requires: erc-8299), and it’s now a running conformance vector — recomputed green end-to-end by three independent implementations, landing as the Step-3×Step-5 entry in the composition note.
Which makes the chain from this thread concrete: if the agent pins the PIM’s CID into sanitization_pipeline_hash (as sketched above), then PIM → WYRIWE → receipt closes through one committed field — a verifier checks not just that input was committed, but that the correct interaction recipe fed it. The manifest describes, the commitment binds, the receipt proves.
Two things where your line-drawing is now the missing piece, and both came up explicitly in that thread:
Canonicalization boundary. TMerlini’s framing — canonicalization is a determinism contract (same action → same bytes → same hash), orthogonal to execution ordering — suggests it sits beside an execution layer rather than inside it. Neither of us wanted to assert where that line falls relative to 8313’s execution model without you drawing it.
The PQ signature slot shape. The receipt capsule reserves a scheme-agnostic attestation slot (sig_pq.type + signerHashed), deliberately not fixing any scheme. I’ve written up the migration path with one costed reference instantiation (ML-DSA-65, real on-chain gas numbers from prior verification work): GitHub - pipavlo82/pq-receipt-profile · GitHub — it maps onto the “fips-204”/“fips-205” placeholder this spec already sketches. But the exact signerHashed shape is your line to draw, not ours to assume — we’d rather pin the slot’s shape with you than around you.
No urgency on either — the slice runs today without them. But if/when 8313 gets its number, both edges are ready to formalize.

I’m considering adding an optional output component to PIMs where the output of individual steps is captured for an auditable trail. The output wouldn’t necessarily need to be stored, instead it can be used as input to a zk-stark. Assuming the PIM is honest and the execution engine followed the steps correctly, the user will always be able to verify the zk-stark.
As a point of clarification, this is intended for both wallets and autonomous agents use so while you are free to incorporate this into your flows it is still independent as a standard.
I would suggest that you use it as part of your receipt rather than execution although if I do add that output then you could use that for the binding portion of the verify instead.

1 Like

The line you drew is exactly the one we hoped you’d draw — output as part of the receipt rather than execution. That’s the same discipline the composition note keeps for Step 5: the receipt accounts, it never executes or gates. PIM stays independent as a standard; the receipt consumes its artifacts without redefining them.
On the optional output component — from the receipt side it drops in cleanly, and here’s the concrete shape: the capsule already carries input_commitment.sanitization_pipeline_hash binding which PIM fed the reasoning. An output trail gives it a natural sibling — a committed hash of the per-step outputs (e.g. output_commitment.step_trail_hash), so a verifier checks not just “the right recipe went in” but “these step results came out,” both recomputable from public bytes. The capsule stays agnostic to how the trail is proven: a plain hash-of-trail works today, and a zk-stark slots in as a stronger proof of the same committed value — same pattern as our anchor field, a pluggable slot with defined shape, conformance tests the recompute, not the mechanism behind it.
One lesson worth importing from the seam we just closed with WYRIWE (three independent implementations, byte-identical): if you add the output component, pin its hashing recipe explicitly from day one — canonicalization of the step outputs, ordering, delimiter, and the empty/genesis case. We found that “sha256(decision ‖ prev)” as shorthand left the genesis preimage underdetermined until it was pinned by elimination; cheaper to state the encoding up front than to rediscover it in conformance. Happy to contribute the test vector for the output-trail case once the shape’s stated — same treatment the Step-3×Step-5 row got.
And on your earlier point about sig_pq.type + signerHashed — both TMerlini and I deliberately left the exact shape as your line to draw, not ours to assume. Whenever you want to pin it, the reserve-the-slot principle is already agreed on both sides; the slot’s shape is yours.
(Small note for the composition-note gist: you’re right that §6 renders after §7 — that’s Panini’s file, I’ll flag it to him.)

Since I’m planning to make the output optional, I may just include both the hash version and the stark version. The hash version is definitely easier but requires knowing all the inputted data. With zk proofs I should be able to define a circuit that allows discrete verification of select data I believe.

Both versions under one slot is exactly the right call — with one structural pin worth making before the shape lands, learned the hard way on the WYRIWE seam.

The dual mechanism stays clean only if both prove the same committed value. If output_commitment.step_trail_hash is the committed object, then: the hash version reveals the trail and lets anyone recompute the hash directly; the stark version proves knowledge of a trail hashing to that same value, revealing only selected steps. Same commitment, two proof mechanisms — conformance tests the recompute of the committed value, not the mechanism, and a verifier that only understands the hash version still interoperates. The failure mode to avoid: if the zk version ends up proving a predicate over the trail without binding to the same step_trail_hash, that’s two different committed objects sharing a field name, and cross-implementation byte-identical conformance becomes undefined for that slot.

On selective disclosure specifically — your circuit intuition is right, and the clean statement shape is probably: “I know trail T such that H(canonical(T)) = step_trail_hash, and steps {i,j} of T are .” The public inputs are the committed hash plus the disclosed steps; everything else stays private. That keeps the hash version as the degenerate case (disclose all steps, no circuit needed) rather than a separate format.

And the day-one pinning list applies to both versions identically, since they share the preimage: canonicalization of step outputs, ordering, delimiter, and the empty-trail/genesis case. We found “sha256(decision ∥ prev)” left the genesis preimage underdetermined until pinned by elimination — cheaper to state the encoding up front than to rediscover it in conformance. Standing offer holds: once the shape is stated, I’ll contribute the test vector for both versions — hash immediately, stark’s public-input encoding as soon as the statement is fixed.