# Coffee Attestations #### Users - **Admin** - approves producers and verifies batches - **Producer** - attests batches - **Customer** - view batch information ### Admin Flow Create attestation to approve producer. - Sign in with email - List Approved Producers - name, description, location, batches - Create new Producer - Enter wallet addresses - *How will the admin get the addresses to add? Producer sends them via email?* - Create attestation - View batches by producer - Verify batch The ApprovedProducer attestation will contain a collection of addresses of approved attesters that are allowed to attest batches. ![image](https://hackmd.io/_uploads/SkK2YqMtR.png) ### Producer Flow - Sign in with email - List batches - Sorted by creation date - Create new batch - Enter batch details - *What data does the producer provide?* - View batch - *What details to display?* - *Can batches be edited? This would create a new attestation and the latest one is always shown* ![image](https://hackmd.io/_uploads/ryupKqMF0.png) ### User Flow - Scan QR to view batch info - *Where does the user find this QR code? Is it printed on the coffee package? If so, the QR needs to be generated for the Producer to print.* - Link to view Producer details ![image](https://hackmd.io/_uploads/SyQca5zFA.png) ### Creating Attestations The wallets are created via email or social sign-in and they will not have any ETH on them. This means the transactions need to be gas sponsored. This will require some research to figure out exactly how. Simplest solution would be OpenZeppelin Relayer but the attester address will be this account. Alchemy AccountKit with ERC4337 and Paymaster for sponsoring gas would set the correct attester address but more complicated. ### Linking users into the application How does the users enter the app? - First time to register account - Every time they attest a new batch - Customers to view the attestation ### Schemas ```ts type Approval { id: string; refUID: string; } type Producer { name: string; metadata: string; attesters: Address[]; // These can attest batches } type Batch { number: string; date: string; metadata: string; } async function createProducer() { } async function verifyProducer() {} async function getProducer(id: string) { return fetchLastUpdatedAttestation(id, schemas.producer); } async function queryProducers(filter: AttestationFilter) { } async function createBatch(batch: Batch) { return fetchLastUpdatedAttestation(id, schemas.batch); } async function getBatch(id: string) {} async function queryBatch(filter: AttestationFilter) {} async function verifyBatch() {} async function fetchLastUpdatedAttestation(id: string, schema: string) { const [attestation, updates] = await Promise.all([ fetchAttestations(schema, { where: { id }, take: 1 }), fetchAttestations(schema, { where: { refUID: id }, take: 10, orderBy: { time: "desc" } }) ]) return updates.length ? updates : attestation; } ```