> For the complete documentation index, see [llms.txt](https://unirep.gitbook.io/unirep/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://unirep.gitbook.io/unirep/getting-started/start-with-typescript/8.-reputation-proof.md).

# 8. Reputation proof

### Generate a reputation proof

See [4. Epoch key proof](https://unirep.gitbook.io/unirep/getting-started/start-with-typescript/pages/1JerVmkBWmXopgmm9GsN#4.-generate-current-user-state) to know how to generate a current user state.

Specify what will be included in the reputation proof:

1. Prove the minimum `posRep-negRep` that an attester gives: `minRep`
2. Prove the [reputation nullifiers](/unirep/protocol/glossary/nullifiers.md#reputation-nullifiers): `nonceList`
3. Prove the graffiti pre-image: `graffitiPreImage`

User should also specify the `attesterId` and `epochKeyNonce` to generate an output epoch key.

```typescript
const attesterID = await contract.attesters(attester.address)
const epkNonce = 0
const rep = userState.getRepByAttester(BigInt(attesterId))
const minRep = Number(rep.posRep) - Number(rep.negRep)
const proveGraffiti = 0 // 0 then it will not prove the pre-image
const nonceList = 0 // 0 or [-1,..,-1] with length 'maxReputationBudget' means the proof will not generate reputation nullifiers.

const proof = await userState.genProveReputationProof(
    attesterId,
    epkNonce,
    minRep,
    proveGraffiti,
    graffitiPreImage,
    nonceList
)
```

### Spend reputation

Call the spendReputation in UniRep smart contract

```typescript
const tx = await contract.spendReputation(
    proof.publicSignals,
    proof.proof,
    {
        value: attestingFee,
    }
)
```

Get the proof index

```typescript
const fromIndex = await contract.getProofIndex(
    proof.hash()
)
```

Use the reputation proof to attest others. To construct another `attestation`, `epochKey`, and `index`, see [5. Attest](/unirep/getting-started/start-with-typescript/5.-attest.md)

```typescript
const tx = await unirepContract
    .connect(attester)
    .submitAttestation(
        attestation, 
        epochKey, 
        index, 
        fromIndex, 
        {
            value: attestingFee,
        }
    )
```

### Verify the proof

with UniRep smart contract:

```typescript
const isValid = await contract.verifyReputation(
    proof.publicSignals,
    proof.proof
)
```

with a prover:

```typescript
const isValid = await proof.verify()
```

### Verify UniRep state

Check global state tree root exits.

```typescript
const isGSTRootExisted = await unirepState.GSTRootExists(
    proof.globalStateTree,
    proof.epoch
)
console.log(isGSTRootExisted) // false then the proof will be invalid
```

Verify reputation nullifiers.

```typescript
const repNullifiers = proof.repNullifiers.map((i) => i.toString())
for (const nullifier of repNullifiers) {
    if (await unirepState.nullifierExist(nullifier)) {
        return false // then the proof will be invalid
    }
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://unirep.gitbook.io/unirep/getting-started/start-with-typescript/8.-reputation-proof.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
