8. Reputation proof
Generate a reputation proof
See 4. Epoch key proof to know how to generate a current user state.
Specify what will be included in the reputation proof:
- Prove the minimum 
posRep-negRepthat an attester gives:minRep - Prove the reputation nullifiers: 
spendAmount - Prove the graffiti pre-image: 
graffitiPreImage 
User should also specify the attesterId and epochKeyNonce to generate an output epoch key.
const attesterID = await contract.attesters(attester.address)
const epkNonce = 0
const rep = await userState.getRepByAttester(attesterID.toBigInt())
const minRep = Number(rep.posRep) - Number(rep.negRep)
const proveGraffiti = 0 // 0 then it will not prove the pre-image
const spendAmount = 0 // 0 if user choose not to generate reputation nullifiers
const proof = await userState.genProveReputationProof(
    attesterId,
    epkNonce,
    minRep,
    proveGraffiti,
    graffitiPreImage,
    spendAmount
)
Spend reputation
Call the spendReputation in UniRep smart contract
const tx = await contract.spendReputation(
    proof.publicSignals,
    proof.proof,
    {
        value: attestingFee,
    }
)
Verify the proof
with UniRep smart contract:
const isValid = await contract.verifyReputation(
    proof.publicSignals,
    proof.proof
)
with a prover:
const isValid = await proof.verify()
Verify UniRep state
Check global state tree root exits.
const isGSTRootExisted = await unirepState.GSTRootExists(
    proof.globalStateTree as string,
    proof.epoch as number
)
console.log(isGSTRootExisted) // false then the proof will be invalid
Verify reputation nullifiers.
const repNullifiers = proof.repNullifiers.map((i) => i.toString())
for (const nullifier of repNullifiers) {
    if (await unirepState.nullifierExist(nullifier)) {
        console.log(false) // then the proof will be invalid
    }
}