verify-dpp — Verify a product's authenticity
verify-dpp is a lightweight web app that lets any secondary buyer or curious consumer verify the authenticity of a Digital Product Passport on-chain, without signing in. A buyer receives a product with a QR code, scans it or enters a serial number, and the app fetches certification events directly from Starknet, validates cryptographic signatures, and displays the product's audit trail.
What it does
When you visit verify-dpp and provide a passport URL or product ID, the app:
Step 1: Scan or enter
QR code on the product, a serial number, or a pasted URL.
Step 2: Query chain
Fetch KeybanPassportCertified events from Starknet, then the VC from IPFS.
Step 3: Verify
Check the ECDSA-P256 signature and validate the certifier in the registry.
Step 4: Show history
Attribute timeline, certifier info, re-certifications.
The entire verification path is trustless: the app never contacts the original brand's backend. All data comes directly from the blockchain and IPFS.
Key features
Multi-event history
Products can be re-certified multiple times (when the brand updates certified attributes or rotates the certification key). verify-dpp shows all certifications, ordered by block number, so you can see the full audit trail:
- Original certification on date X
- Re-certification on date Y (e.g., after a supply chain update)
- Current state reflecting the latest changes
Each event is independently verifiable.
Attribute timeline
If a field changes across certifications, verify-dpp displays the history:
| Field | Event 1 | Event 2 | Current |
|---|---|---|---|
vintage | 2020 | 2020 | 2020 |
alcohol | 13.5% | 14% | 14% |
origin | France | France | France |
This is useful for tracking supply chain updates, corrections, or enrichment over time.
Encrypted field support
Some passports encrypt sensitive data (IBAN, serial numbers, PII) before certification. When verify-dpp encounters an encrypted field:
- It shows a placeholder badge (Encrypted)
- It asks you to provide the decryption key (usually distributed separately via SMS or email)
- Once you provide the key, it decrypts the field and displays the plaintext
Keys can be shared globally (one key for all fields) or per-field (granular control).
Claim overlay
If you have a claim document (JSON) from the brand or a third party, you can paste or upload it. verify-dpp will compare your claim against the certified attributes and flag mismatches:
| Field | Certified | Your claim | Status |
|---|---|---|---|
productName | Wine Bottle 2020 | Wine Bottle 2020 | Valid |
vintage | 2020 | 2020 | Valid |
alcohol | 14% | 13.5% | Mismatch |
This lets you spot discrepancies before you trust the product.
Certifier validation
verify-dpp fetches the certifier's info from the Starknet registry contract:
- Certifier name — Human-readable identifier registered on-chain
- Validity status — Active or Revoked (you can trust active certifiers; revoked ones may have had key compromises)
- Certification key — Recovered from the W3C VC's
issuerDID and checked against the registry
If a certifier is revoked, verify-dpp will warn you before showing verified attributes.
URL parameters
verify-dpp is a URL-driven app. You can encode all the information needed to verify directly in the link, so shares via QR code or email work seamlessly:
| Parameter | Example | Effect |
|---|---|---|
productId | ?productId=550e8400-e29b-41d4-a716-446655440000 | Auto-load this product's events |
claim | ?claim=%7B%22productName%22%3A...%7D | Overlay this claim for comparison |
encryptionKey | ?encryptionKey=base64-encoded-key | Decrypt all encrypted fields with this key |
encryptionKeys | ?encryptionKeys=%7B%22iban%22%3A...%7D | Per-field decryption keys (JSON object) |
chain | ?chain=mainnet or ?chain=sepolia | Select Starknet network (default: mainnet) |
certifierAddress | ?certifierAddress=0x... | Custom certifier contract (comma-separated for multiple) |
startBlock | ?startBlock=2000000 | Lower bound for the Starknet event scan (default: chain-specific) |
Query parameters are recorded by browsers, web servers, CDN access logs, analytics, and the Referer header. Treat any value passed in ?encryptionKey= or ?encryptionKeys= as likely to leak.
For confidential payloads, prefer one of:
- URL fragment (
#encryptionKey=...): fragments are never sent to servers and stay client-side - Out-of-band channel: print the key on a packing slip, send it via SMS, and let the buyer paste it into the in-app prompt
- Per-field keys scoped to non-sensitive metadata only
Example: a textile brand's QR code might link to:
https://verify-dpp.keyban.io/?productId=00000000-0000-4000-8000-000000000001&chain=mainnet
When a buyer scans it, the app immediately queries events for that product ID. Try the link yourself — the demo passport in the buyer tutorial covers the same productId alongside an electronics and a cosmetics example.
UI flow
- Scan or paste
QR code on the product, a serial number, or a passport URL.
- Blockchain lookup
Query certification events directly from Starknet RPC.
- View history
See all certifications, attribute timeline, and certifier info.
- Decrypt (optional)
Provide encryption keys to unlock sensitive fields.
- Verify result
Cryptographic signature checked, audit trail displayed.
Why trustless matters
The classic DPP flow relies on the original brand's backend to answer "Is this product authentic?" But what if:
- The brand's app is decommissioned or taken offline?
- The brand's database is compromised?
- The brand goes out of business?
With verify-dpp's trustless model, you can audit any product forever — even years after the brand stops maintaining their infrastructure. The blockchain and IPFS are your source of truth.
Advanced features
Custom RPC URL
By default, verify-dpp uses a public Starknet RPC endpoint. If you operate your own RPC node or hit rate limits, the app exposes an Advanced form field where you can paste a custom RPC URL. The value is held in the app state only — there is no URL parameter for it, on purpose (see the warning below).
:::warning Trust implications
A malicious RPC node can fabricate KeybanPassportCertified events and make a counterfeit product appear verified. The custom RPC URL is intentionally kept out of the URL parameter set so it cannot be embedded in a QR code, packing slip, or email campaign and silently redirected. Operators who need a private RPC should configure it through the in-app form, not through a shareable link.
:::
Network selection
verify-dpp supports multiple Starknet networks:
mainnet— Production (default)sepolia— Testnetdevnet— Local development
Pass ?chain=sepolia to test on testnet before going live.
Multiple certifiers
If an organization has multiple certification contracts on different addresses, you can query all of them:
?certifierAddress=0x...,0x...
Related concepts
- DPP Certification and Trust Chain — How certification works under the hood: P-256 keys, W3C VCs, content hashing, key rotation, trustless verification.
- Digital Product Passport — The full four-step lifecycle from build to claim.
- Embedded Wallet — The wallet powering token claims.
KeybanDppCertifierCairo contract — Source of the on-chainKeybanPassportCertifiedevent the app reads.
Deployment
verify-dpp is deployed as a static web app to IPFS for maximum resilience. There is no server to take down. Updates are published as new IPFS CIDs, and the backend's subdomain middleware routes verify-dpp.your-domain.com to the latest deployment.
Next steps
- Brand side: Use the admin console to configure organizations, certification keys, and DPP passports.
- Consumer side: Share verify-dpp links via QR codes on product packaging, packing slips, or email campaigns.
- Integration: Reference the Embedded Wallet SDK if you want to build custom verification UIs.