@cognitiveproof/c2pa-react-ddex-component
v0.1.0
Published
A React plugin for c2pa-react-component that renders DDEX (Digital Data Exchange) ERN release, resource, party, and deal data from a C2PA manifest.
Maintainers
Readme
@cognitiveproof/c2pa-react-ddex-component
A plugin for c2pa-react-component that renders DDEX (Digital Data Exchange) release data — party, release, resource, and deal information carried in a C2PA manifest's org.mixotron.ddex custom claim — at three progressive levels of detail.
Requirements
This package is a plugin for c2pa-react-component. Install both:
npm install @cognitiveproof/c2pa-react-ddex-component c2pa-react-componentPeer dependencies
| Package | Version |
|---|---|
| react | ^18.0.0 \|\| ^19.0.0 |
| react-dom | ^18.0.0 \|\| ^19.0.0 |
CSS
Import the stylesheet once at the root of your app:
import "@cognitiveproof/c2pa-react-ddex-component/style.css";Next.js App Router — add it to app/layout.tsx:
import "@cognitiveproof/c2pa-react-ddex-component/style.css";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<body>{children}</body>
</html>
);
}Usage
Pass DDEXManifest as a plugin to the C2paManifest component from c2pa-react-component:
import { C2paManifest } from "c2pa-react-component";
import { DDEXManifest } from "@cognitiveproof/c2pa-react-ddex-component";
import type { VerificationOutcome } from "c2pa-react-component-types";
import "@cognitiveproof/c2pa-react-ddex-component/style.css";
export function MediaCard({ outcome }: { outcome: VerificationOutcome }) {
return (
<C2paManifest
manifest={outcome}
plugin={[DDEXManifest]}
/>
);
}Component
DDEXManifest
Renders org.mixotron.ddex DDEX release data from a C2PA manifest at a configurable level of detail. Returns null when the active manifest has no org.mixotron.ddex assertion.
import { DDEXManifest } from "@cognitiveproof/c2pa-react-ddex-component";
<DDEXManifest manifest={verificationOutcome} level={1} />Props
| Prop | Type | Default | Description |
|---|---|---|---|
| manifest | VerificationOutcome | required | Verification result from the C2PA SDK |
| level | 1 \| 2 \| 3 | 1 | Initial disclosure level |
| className | string | — | CSS class applied to the root element |
Disclosure levels
| Level | What is shown |
|---|---|
| 1 | Compact card: release title, artist(s), genre and parental-warning badges, "More Info" button |
| 2 | Extends level 1 with label, UPC, ℗/© line, track list (with ISRC), and deal summaries (commercial model, use type, price, territory, validity) |
| 3 | Full breakdown of the DDEX message — release, all tracks with resolved per-track artists, all deals with full territory/pricing/validity detail, the full party list, and message header (message ID and created timestamp) |
Clicking "More Info" advances from level 1 → 2 → 3. Clicking "Small View" at level 3 returns to level 1.
Data shape
The plugin reads the org.mixotron.ddex assertion, which mirrors a simplified DDEX ERN message:
type DdexAssertion = {
MessageHeader?: { MessageId?: string; MessageCreatedDateTime?: string };
PartyList?: { PartyReference?: string; PartyName?: { FullName?: string } }[];
ReleaseList?: { Release?: DdexRelease[] };
ResourceList?: { SoundRecording?: DdexSoundRecording[] };
DealList?: { ReleaseDeal?: DdexReleaseDeal[] };
};DisplayArtist entries reference parties by ArtistPartyReference, and releases reference their tracks by ReleaseResourceReferenceList (matched against each SoundRecording's ResourceReference); the plugin resolves both automatically. See examples/ for full sample manifests, including a single-track release, a multi-artist album with multiple deals, and a minimal manifest with no party or deal data.
Converting between JSON and XML
The package also exports the JSON↔XML conversion used by the L3 "Download XML" button, so consumers can convert DDEX files to whichever format they need without depending on the DDEXManifest component at all:
import { ddexAssertionToXml, xmlToDdexAssertion } from "@cognitiveproof/c2pa-react-ddex-component";
import type { DdexAssertion } from "@cognitiveproof/c2pa-react-ddex-component";
// JSON -> a simplified DDEX ERN NewReleaseMessage XML document
const xml: string = ddexAssertionToXml(assertion);
// XML -> the same JSON assertion shape
const roundTripped: DdexAssertion = xmlToDdexAssertion(xml);ddexAssertionToXmlhas no environment requirements — it only builds a string.xmlToDdexAssertionparses withDOMParser, so it needs a browser or a DOM-compatible environment (e.g. jsdom in tests); it throws ifDOMParserisn't available, and throws with a message containing"Invalid DDEX XML"if the input doesn't parse.- Both functions omit absent sections/fields rather than emitting empty elements, so
xmlToDdexAssertion(ddexAssertionToXml(assertion))round-trips back to a structurally equalassertionfor any shape this project renders — seesrc/server/ddex/convert.test.ts.
Types
Types are provided by the shared c2pa-react-component-types package, which is installed automatically as a dependency.
import type {
VerificationOutcome,
Manifest,
ManifestStore,
PluginC2PA,
} from "c2pa-react-component-types";This package also exports its own DDEX-related types (DdexAssertion, DdexRelease, DdexSoundRecording, DdexReleaseDeal, etc.) and helper functions (getDdexAssertion, getArtistNames, getSoundRecordingsForRelease, formatPrice, and more) — see src/components/Ddex/ddexAssertion.ts.
Local development
Use yalc to consume the library in another local project without publishing to npm.
Install yalc globally (once):
npm install -g yalcStart watch mode in this repo:
# Terminal 1 — rebuild on every save
npm run dev:lib
# Terminal 2 — push updates to yalc's local store
yalc push --watchIn your consuming project:
yalc add @cognitiveproof/c2pa-react-ddex-component
npm installRevert to the published npm version:
yalc remove @cognitiveproof/c2pa-react-ddex-component
npm installLicense
MIT © Cognitive Proof — see LICENSE.
