# PVA Universal Certificate-Contract — Template Pack (v1)
Use this anywhere (static hosting, Next.js, IPFS, or server render). It’s a single visual template with brand styling and placeholder fields. Fill it with JSON, query params, or a tiny Node script.
---
## 1) `certificate-template.html` (universal)
```html
{{ assetTitle }} — PVA Certified ContractCertificate Admission Form
Signed by PVA keys. Any alteration invalidates this document.
{{ docHash }}
Asset Page
Parties & Signatures
Authorized Signatory (PVA Bazaar)
Name: {{ pvaSigner }}
Date: {{ signDate }}
Owner / Recipient
Name: {{ ownerName }}
Wallet: {{ ownerWallet }}
const filled = fillTemplate(template, data);
fs.mkdirSync(path.dirname(path.resolve(outPath)), { recursive: true });
fs.writeFileSync(path.resolve(outPath), filled, 'utf8');
console.log('✅ Rendered:', outPath);
```
**Example `data.json`**
```json
{
"assetTitle": "Maradjet — Emerald Pendant #1",
"assetImage": "https://images.squarespace-cdn.com/.../emerald_pendant_1.jpg",
"contractId": "PVA-2025-0001",
"issueDate": "2025-09-12",
"version": "v1.0",
"pvaSerial": "PVABZ-AEM-00001",
"tokenId": "0",
"contractAddress": "0x3b3af296e521a0932041cc5599ea47ec2d4ef8a5",
"chain": "Base Mainnet (8453)",
"ipfsCid": "ipfs://bafy.../0.json",
"species": "Natural Beryl (Emerald)",
"shape": "Mounted",
"measurements": "—",
"weight": "~1.47 ct (stone); pendant 18k + 10k chain",
"color": "Vivid green",
"transparency": "Mounted",
"enhancements": "Undisclosed",
"origin": "Panjshir",
"mintedBy": "PVA Bazaar Vault",
"creatorWallet": "0xC0FfEe...bEEF",
"owner": "PVA Admin",
"royalties": "10% (EIP-2981)",
"metadataNote": "Lab scans + images pinned to IPFS",
"notes": "Grades & weights approximated when mounted",
"qrCertificate": "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=https%3A%2F%2Fpvabazaar.org%2Fverify%3Fid%3DPVA-2025-0001",
"qrAsset": "https://api.qrserver.com/v1/create-qr-code/?size=220x220&data=https%3A%2F%2Fopensea.io%2Fitem%2Fbase%2F0x3b3af296e521a0932041cc5599ea47ec2d4ef8a5%2F0",
"docHash": "sha256: 7f3c…91ad",
"pvaSigner": "Authorized Signer",
"signDate": "2025-09-12",
"ownerName": "Buyer Name",
"ownerWallet": "0x...",
"verificationUrl": "https://pvabazaar.org/verify?id=PVA-2025-0001"
}
```
---
## 3) `render-pdf.js` (Node+Puppeteer → PDF)
```js
// Usage: node render-pdf.js ./out/certificate.html ./out/certificate.pdf
const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer');
(async () => {
const [,, htmlPath, pdfPath] = process.argv;
if(!htmlPath || !pdfPath){
console.error('Usage: node render-pdf.js ');
process.exit(1);
}
const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();
const html = fs.readFileSync(path.resolve(htmlPath),'utf8');
await page.setContent(html, { waitUntil: 'networkidle0' });
await page.pdf({ path: path.resolve(pdfPath), format: 'A4', printBackground: true, margin: { top:'12mm', right:'12mm', bottom:'12mm', left:'12mm' } });
await browser.close();
console.log('📄 PDF saved:', pdfPath);
})();
```
> Tip: For Vercel/Next.js, you can put the HTML in a React component and pass props from your API or route (`/provenance/[serial]`). The placeholders map directly to component props.
---
## 4) Drop‑in (no server) usage
* Host `certificate-template.html` on any static host.
* Link with a `data` query param:
```
https://yourhost/certificate-template.html?data={"assetTitle":"Maradjet","assetImage":"https://...jpg","tokenId":"0"}
```
The small inline script fills the values on load—no build step needed.
---
## 5) Field Reference (keep consistent)
```
contractId, issueDate, version, assetTitle, assetImage, pvaSerial,
tokenId, contractAddress, chain, ipfsCid,
species, shape, measurements, weight, color, transparency, enhancements, origin,
mintedBy, creatorWallet, owner, royalties, metadataNote, notes,
qrCertificate, qrAsset, docHash, pvaSigner, signDate, ownerName, ownerWallet,
verificationUrl
```
---
## 6) Next steps
* If you want, I can add a **Next.js dynamic route** `/provenance/[serial]` that fetches data (OpenSea, IPFS, or your DB) and renders this template automatically.
* Or I can wire the **mint flow** to generate and pin the filled HTML/PDF to **IPFS** on creation.
PVA Certificates — Preview
💎
PVA Provenance & Authenticity Certificates
Wrapped third‑party lab results with PVA on‑chain envelope
PVA BazaarLab Verified
3rd‑Party Report
Lab / Source
Galaxy Gemological Institute (GGI)
Report Type
Gemstone Jewellery Report
Date
23 July 2025
Certificate #
PEW2507790572
Object
Ring set with Natural Beryl (Natural Emerald)
Species / Variety
Natural Beryl / Natural Emerald
Origin
Chitral, Pakistan (as noted)
Weight (ct)
17.0
Measurements (mm)
22.39 × 13.3 × 8.15
Shape & Cut
Cushion & Mixed Cut
Color
Green
Transparency
Semi-Transparent
Description
A ring weighing 24.508 grams.
Comments
Evidence of moderate oiling is found. Testing indicates characteristics of emerald from Chitral, Pakistan.
This preview wraps the provided lab information in PVA’s branded certificate layout. On mint, a unique on‑chain envelope ID, contract, tokenId and IPFS CID will be embedded here.
PVA BazaarLab Verified
3rd‑Party Report
Lab / Source
Galaxy Gemological Institute (GGI)
Report Type
Gemstone Report
Date
11 September 2025
Certificate #
PEW2509920297
Object
One Cabochon Cut Gemstone
Species
Natural Corundum
Variety
Natural Star Sapphire
Origin
Africa
Weight (ct)
233.47
Measurements (mm)
39.60 × 31.53 × 16.83
Shape
Round
Cut
Cabochon
Color
Grayish Pink
Transparency
Semi-Translucent
Comments
No evidence of enhancement found.
Gemologist
Mohammad Ali (GIA USA)
This preview wraps the provided lab information in PVA’s branded certificate layout. On mint, a unique on‑chain envelope ID, contract, tokenId and IPFS CID will be embedded here.