
Security News
US Government Forces Anthropic to Pull Claude Fable Days After Launch
Anthropic says the directive cited national security concerns over a narrow jailbreak, but offered no specific technical details.
Portable DP-1 playlist and Feral File channel parsers, validators, and Ed25519 signer (browser + Node) using Zod & noble-ed25519
A lightweight JavaScript SDK for parsing, validating, and signing DP-1 playlists and Feral File channels in both Node.js and browser environments.
dp1-js provides the foundation for DP-1 tooling and FF1 apps to verify playlist and channel structure and optionally sign them with Ed25519 private keys. It creates detached signatures compatible with DP-1's signatures[] evolution, enabling secure and verifiable digital display protocols.
npm install dp1-js
Or use the library directly in the browser via CDN:
Using ES Modules (Modern Browsers):
<script type="module">
import {
parseDP1Playlist,
parseChannel,
signDP1Playlist,
verifyPlaylistSignature,
signChannel,
verifyChannelSignature,
} from 'https://cdn.jsdelivr.net/npm/dp1-js/dist/index.js';
// Use the functions
const playlistResult = parseDP1Playlist(playlistData);
const channelResult = parseChannel(channelData);
</script>
import { parseDP1Playlist } from 'dp1-js';
// Parse and validate playlist JSON
const result = parseDP1Playlist(jsonData);
if (result.error) {
console.error('Validation failed:', result.error.message);
// Access detailed error information
result.error.details?.forEach(detail => {
console.error(` ${detail.path}: ${detail.message}`);
});
} else {
console.log('Valid playlist:', result.playlist);
}
import { signDP1Playlist } from 'dp1-js';
const playlist = {
dpVersion: '1.0.0',
id: 'playlist-123',
slug: 'my-playlist',
title: 'My Playlist',
items: [
{
id: 'item-1',
title: 'Artwork 1',
source: 'https://example.com/artwork1.html',
duration: 30,
license: 'open',
created: '2025-01-01T00:00:00Z',
},
],
};
// Sign with Ed25519 private key (as hex string or Uint8Array)
const signature = await signDP1Playlist(
playlist,
privateKeyHex // or privateKeyBytes as Uint8Array
);
console.log('Signature:', signature);
// Output: "ed25519:0x<hex_signature>"
// Add signature to playlist
const signedPlaylist = {
...playlist,
signature,
};
import { verifyPlaylistSignature } from 'dp1-js';
// Playlist with signature
const signedPlaylist = {
dpVersion: '1.0.0',
id: 'playlist-123',
slug: 'my-playlist',
title: 'My Playlist',
items: [
{
id: 'item-1',
title: 'Artwork 1',
source: 'https://example.com/artwork1.html',
duration: 30,
license: 'open',
created: '2025-01-01T00:00:00Z',
},
],
signature: 'ed25519:0x...',
};
// Verify with Ed25519 public key (Uint8Array)
const isValid = await verifyPlaylistSignature(signedPlaylist, publicKeyBytes);
if (isValid) {
console.log('✓ Signature is valid');
} else {
console.log('✗ Signature verification failed');
}
import { parseChannel } from 'dp1-js';
// Parse and validate channel JSON
const result = parseChannel(channelData);
if (result.error) {
console.error('Validation failed:', result.error.message);
result.error.details?.forEach(detail => {
console.error(` ${detail.path}: ${detail.message}`);
});
} else {
console.log('Valid channel:', result.channel);
}
import { signChannel } from 'dp1-js';
const channel = {
id: 'channel-123',
slug: 'my-channel',
title: 'My Channel',
playlists: ['https://example.com/playlist1', 'https://example.com/playlist2'],
created: '2025-01-01T00:00:00Z',
};
// Sign with Ed25519 private key (as hex string or Uint8Array)
const signature = await signChannel(channel, privateKeyHex);
console.log('Signature:', signature);
// Output: "ed25519:0x<hex_signature>"
// Add signature to channel
const signedChannel = {
...channel,
signature,
};
import { verifyChannelSignature } from 'dp1-js';
// Channel with signature
const signedChannel = {
id: 'channel-123',
slug: 'my-channel',
title: 'My Channel',
playlists: ['https://example.com/playlist1'],
signature: 'ed25519:0x...',
};
// Verify with Ed25519 public key (Uint8Array)
const isValid = await verifyChannelSignature(signedChannel, publicKeyBytes);
if (isValid) {
console.log('✓ Signature is valid');
} else {
console.log('✗ Signature verification failed');
}
parseDP1Playlist(json: unknown): DP1PlaylistParseResultParses and validates playlist data from unknown JSON input.
Parameters:
json - Unknown JSON data to parse and validateReturns: DP1PlaylistParseResult object containing either:
playlist - The validated Playlist object (if successful)error - Detailed error information (if validation failed)
type: "invalid_json" | "validation_error"message: Human-readable error messagedetails: Array of specific validation errors with pathsExample:
const result = parseDP1Playlist(data);
if (result.playlist) {
// Use validated playlist
console.log(result.playlist.title);
}
signDP1Playlist(playlist: Omit<Playlist, "signature">, privateKey: Uint8Array | string): Promise<string>Signs a playlist using Ed25519 as per DP-1 specification.
Parameters:
playlist - Playlist object without signature fieldprivateKey - Ed25519 private key as hex string or Uint8ArrayReturns: Promise resolving to signature string in format "ed25519:0x<hex>"
Example:
const sig = await signDP1Playlist(playlist, '0x1234...');
verifyPlaylistSignature(playlist: Playlist, publicKey: Uint8Array): Promise<boolean>Verifies a playlist's Ed25519 signature using the provided public key.
Parameters:
playlist - Playlist object with signature fieldpublicKey - Ed25519 public key as Uint8Array (32 bytes)Returns: Promise resolving to true if signature is valid, false otherwise
Example:
const isValid = await verifyPlaylistSignature(signedPlaylist, publicKeyBytes);
if (isValid) {
console.log('Signature verified successfully');
}
Note: The function returns false if:
parseChannel(json: unknown): ChannelParseResultParses and validates channel data from unknown JSON input.
Parameters:
json - Unknown JSON data to parse and validateReturns: ChannelParseResult object containing either:
channel - The validated Channel object (if successful)error - Detailed error information (if validation failed)
type: "invalid_json" | "validation_error"message: Human-readable error messagedetails: Array of specific validation errors with pathsExample:
const result = parseChannel(data);
if (result.channel) {
// Use validated channel
console.log(result.channel.title);
}
signChannel(channel: Omit<Channel, "signature">, privateKey: Uint8Array | string): Promise<string>Signs a channel using Ed25519 as per DP-1 specification.
Parameters:
channel - Channel object without signature fieldprivateKey - Ed25519 private key as hex string or Uint8ArrayReturns: Promise resolving to signature string in format "ed25519:0x<hex>"
Example:
const sig = await signChannel(channel, '0x1234...');
verifyChannelSignature(channel: Channel, publicKey: Uint8Array): Promise<boolean>Verifies a channel's Ed25519 signature using the provided public key.
Parameters:
channel - Channel object with signature fieldpublicKey - Ed25519 public key as Uint8Array (32 bytes)Returns: Promise resolving to true if signature is valid, false otherwise
Example:
const isValid = await verifyChannelSignature(signedChannel, publicKeyBytes);
if (isValid) {
console.log('Signature verified successfully');
}
The library exports comprehensive TypeScript types for DP-1 playlists and channels:
// Functions
import {
parseDP1Playlist,
parseChannel,
signDP1Playlist,
verifyPlaylistSignature,
signChannel,
verifyChannelSignature,
} from 'dp1-js';
// Types
import type {
Playlist,
Channel,
PlaylistItem,
DisplayPrefs,
Provenance,
Repro,
Entity,
DynamicQuery,
DP1PlaylistParseResult,
ChannelParseResult,
} from 'dp1-js';
Playlist - Complete playlist structure with metadata and itemsPlaylistItem - Individual item in a playlistDisplayPrefs - Display preferences for artwork renderingProvenance - On-chain or off-chain provenance informationRepro - Reproduction and verification metadataEntity - Curator or publisher informationDynamicQuery - Dynamic query configuration for live contentChannel - Complete channel structure with playlist references and metadataDP1PlaylistParseResult - Result type from parsing playlist operationChannelParseResult - Result type from parsing channel operationSee types.ts for complete type definitions.
This package exposes small validation helpers that do not require consumers to import our internal schemas.
Available validators:
validateDpVersion(version: string) → ValidationResultvalidateDisplayPrefs(input: unknown) → ValidationResultvalidateRepro(input: unknown) → ValidationResultvalidateProvenance(input: unknown) → ValidationResultvalidatePlaylistItem(input: unknown) → ValidationResultvalidateDynamicQuery(input: unknown) → ValidationResultvalidateEntity(input: unknown) → ValidationResultvalidateChannel(input: unknown) → ValidationResultUsage examples:
import { validateProvenance } from 'dp1-js';
const provenance = {
type: 'onChain',
contract: { chain: 'evm', address: '0xabc', tokenId: '42' },
};
const res = validateProvenance(provenance);
if (!res.success) {
console.error(res.error.message);
res.error.issues.forEach(i => console.error(`${i.path}: ${i.message}`));
}
ValidationResult shape:
type ValidationIssue = { path: string; message: string };
type ValidationResult =
| { success: true }
| { success: false; error: { message: string; issues: ValidationIssue[] } };
You can also integrate these validators into your own schema library (e.g., Zod) via .refine or .superRefine to attach issues to your app's error format.
A valid DP-1 playlist includes:
{
dpVersion: "1.0.0", // DP-1 protocol version
id: "unique-id", // Unique playlist identifier
slug: "url-friendly-slug", // URL-friendly identifier
title: "Playlist Title", // Human-readable title
created?: "ISO-8601-date", // Optional creation timestamp
defaults?: { // Optional default settings
display?: {...},
license?: "open" | "token" | "subscription",
duration?: 30
},
items: [...], // Array of playlist items
signature?: "ed25519:0x..." // Optional Ed25519 signature
}
A valid Feral File channel includes:
{
id: "uuid", // Unique channel identifier
slug: "url-friendly-slug", // URL-friendly identifier
title: "Channel Title", // Human-readable title
created?: "ISO-8601-date", // Optional creation timestamp
curator?: "string", // Optional curator name
curators?: [...], // Optional array of curator entities
summary?: "string", // Optional channel description
publisher?: {...}, // Optional publisher entity
playlists: [...], // Array of playlist URLs
coverImage?: "URI", // Optional cover image URI
signature?: "ed25519:0x..." // Optional Ed25519 signature
}
npm install
npm run build
Builds ESM, CJS, and TypeScript declaration files to dist/.
npm test
npm run lint
node:crypto with Ed25519 support)Contributions are welcome! Please ensure:
npm test)npm run lint)For issues and questions:
FAQs
Portable DP-1 playlist and Feral File channel parsers, validators, and Ed25519 signer (browser + Node) using Zod & noble-ed25519
We found that ff-dp1-js demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Anthropic says the directive cited national security concerns over a narrow jailbreak, but offered no specific technical details.

Security News
A network of 152 Chrome live wallpaper extensions hid ad tracking and made extension-driven traffic look like Google search clicks.

Company News
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.