> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kineticvm.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Buyer verification

> Check every row of a listing against the ERC-8004 Validation Registry on Monad, then pay and unlock the files.

A buyer should not trust the marketplace's word that a dataset is real. Every row names a validation request on Monad, and anyone can read that request. Paying comes after that check.

## What one row proves

For each manifest row the buyer, or the marketplace verify route, calls `getValidationStatus(requestHash)` on the Validation Registry at `0x8004Cb1BF31DAf7788923b405b754f57acEB4272`.

The row is accepted only when all of these hold:

| Field | Required value |
| - | - |
| Agent id | The listing's agent |
| Validator | `KineticAttestor`, `0x6e46d149b7d3396b42E874765Cf5a1bb26BD5bA5` |
| Response | `100` |
| Response hash | The row's `paramsHash` |
| Tag | `kinetic-action`, when a tag is present |

`paramsHash` is keccak256 of one exact line of `operations.jsonl`. After unlock, the buyer repeats that hash on the file they received. One changed character, one reordered key, or one extra space makes the line fail.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
cast call 0x8004Cb1BF31DAf7788923b405b754f57acEB4272 \
  "getValidationStatus(bytes32)(address,uint256,uint8,bytes32,string,uint256)" \
  0xREQUEST_HASH \
  --rpc-url https://testnet-rpc.monad.xyz
```

The return is `validator, agentId, response, responseHash, tag, lastUpdate`.

<Warning>
  Response `100` means the device key bound to this agent signed those exact bytes, and the owner had approved the attestor. It does not mean a motor turned or a sensor was calibrated. Read [what an attestation proves](/concepts/attestations#what-an-attestation-proves) before you treat a dataset as ground truth.
</Warning>

## Verify before you pay

On a listing page, verification calls `POST /api/marketplace/listings/<slug>/verify`. That route reads the pinned manifest, not the data file, and runs the table above for every row. The response includes the row count and the first eight rows, each with its index, `paramsHash`, and `requestHash`.

You can do the same call yourself:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl -X POST https://marketplace.kineticvm.xyz/api/marketplace/listings/SLUG/verify
```

A listing that fails any row does not verify. Publish checks that the files agree with each other and that the key's wallet still owns the agent. It does not write a "verified" flag. This call is the check, and it reads Monad at the moment you make it.

## Pay and unlock

<Steps>
  <Step title="Send MON to the payout address">
    The listing page shows the seller's payout address and the price. Send at least that amount, from the wallet you will use to unlock. A transfer to any other address does not count.
  </Step>

  <Step title="Sign the unlock message">
    With the same wallet, sign this personal message, with the listing slug and the transaction hash:

    ```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    KineticVM marketplace
    Unlock
    listing: <slug>
    tx: 0x…
    ```
  </Step>

  <Step title="Submit both">
    The marketplace reads the transaction on Monad testnet. It must be successful, `from` the signer, `to` the payout address, and worth at least the listing price. A transaction hash can unlock one purchase, once.
  </Step>

  <Step title="Download">
    The response includes access to the data file and the manifest. Recompute keccak256 of each line and compare it to `paramsHash`, then compare `paramsHash` to `responseHash` on chain.
  </Step>
</Steps>

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
cast keccak operations-line.json
```

`cast keccak` hashes the raw file bytes. Hash the line exactly as stored, with no added newline, and compare the result to the manifest.

## A buyer's checklist

<AccordionGroup>
  <Accordion title="The agent is the machine you think it is" icon="fingerprint">
    `ownerOf(agentId)` on the Identity Registry names the seller. The agent URI set at claim carries the device name. Neither proves the hardware is honest. They tell you which identity produced the signatures.
  </Accordion>

  <Accordion title="The validator is KineticAttestor" icon="badge-check">
    A validation from some other contract is a different scheme. The verify route rejects it, and so should a buyer checking by hand.
  </Accordion>

  <Accordion title="The file matches the manifest" icon="file-check">
    Line count, order, and keccak256 of each line. The manifest is the index. The data file is the thing you paid for. Both have to agree, and both have to agree with the chain.
  </Accordion>

  <Accordion title="The license matches your use" icon="scale">
    `research` and `commercial` allow training and forbid resale of the raw file. `audit` allows review and forbids training. The license is a term on the listing, not something the chain enforces.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.