
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@opennote-ed/sdk
Advanced tools
This is the official Typescript SDK for the Opennote API, providing access to both Video and Journals APIs. Read the documentation here and see more examples.
npm install opennote
# or
yarn add opennote
# or
pnpm add opennote
# or
bun add opennote
import { OpennoteClient } from 'opennote';
// Initialize the client with your API key
const client = new OpennoteClient(process.env.OPENNOTE_API_KEY || 'your_api_key');
import { OpennoteClient, VideoAPIRequestMessage } from 'opennote';
const client = new OpennoteClient(process.env.OPENNOTE_API_KEY || '');
// Define the messages for video generation
const messages: VideoAPIRequestMessage[] = [
{
role: "user",
content: "Make a video about the Silk Road"
}
];
// Create a video job
const response = await client.video.create({
model: "picasso",
messages: messages,
include_sources: true,
search_for: "Silk Road History",
source_count: 5,
upload_to_s3: true,
title: "The Silk Road",
});
console.log(`Video ID: ${response.video_id}`);
// Poll for video status
const status = await client.video.status(response.video_id);
if (status.status === "completed" && status.response) {
console.log(`Video URL: ${status.response.s3_url}`);
} else if (status.status === "pending") {
console.log("Video is still processing...");
} else if (status.status === "failed") {
console.error("Video generation failed:", status.error);
}
import { OpennoteClient, VideoAPIRequestMessage } from 'opennote';
// Helper function to sleep
function sleep(ms: number): Promise<void> {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function createVideoWithPolling() {
const client = new OpennoteClient(process.env.OPENNOTE_API_KEY || '');
try {
// Create video
const response = await client.video.create({
model: "picasso",
messages: [{ role: "user", content: "Explain quantum computing" }],
include_sources: true,
upload_to_s3: true,
title: "Quantum Computing Explained",
});
if (!response.success || !response.video_id) {
throw new Error(`Failed to create video: ${response.message}`);
}
// Poll for completion
let status;
do {
await sleep(15000); // Wait 15 seconds between checks
status = await client.video.status(response.video_id);
console.log(`Status: ${status.status}`);
} while (status.status === "pending");
if (status.status === "completed" && status.response?.s3_url) {
console.log(`Video ready: ${status.response.s3_url}`);
} else {
console.error("Video generation failed:", status.error);
}
} catch (error) {
console.error("Error:", error);
}
}
import { OpennoteClient } from 'opennote';
const client = new OpennoteClient(process.env.OPENNOTE_API_KEY || '');
// Get all journals
const journalsResponse = await client.journals.list();
if (journalsResponse.success && journalsResponse.journals) {
journalsResponse.journals.forEach(journal => {
console.log(`${journal.title} (ID: ${journal.id})`);
console.log(` Created: ${journal.created_at}`);
console.log(` Updated: ${journal.updated_at}`);
});
}
// Handle pagination
if (journalsResponse.next_page_token) {
const nextPage = await client.journals.list(journalsResponse.next_page_token);
}
// Get content of a specific journal
const journalId = 'your-journal-id';
const contentResponse = await client.journals.content(journalId);
if (contentResponse.success && contentResponse.content) {
console.log(`Title: ${contentResponse.title}`);
console.log(`Content: ${contentResponse.content}`);
console.log(`Last updated: ${contentResponse.timestamp}`);
}
import { OpennoteClient } from 'opennote';
async function displayAllJournals() {
const client = new OpennoteClient(process.env.OPENNOTE_API_KEY || '');
try {
// List all journals
const journalsResponse = await client.journals.list();
if (!journalsResponse.success || !journalsResponse.journals) {
throw new Error('Failed to fetch journals');
}
// Display each journal's content
for (const journal of journalsResponse.journals) {
console.log(`\n=== ${journal.title} ===`);
const content = await client.journals.content(journal.id);
if (content.success && content.content) {
console.log(content.content);
}
}
} catch (error) {
console.error('Error:', error);
}
}
const client = new OpennoteClient(
apiKey: string, // Required: Your Opennote API key
baseUrl?: string, // Optional: API base URL (default: "https://api.opennote.com")
timeout?: number, // Optional: Request timeout in ms (default: 60000)
maxRetries?: number // Optional: Max retry attempts (default: 3)
);
client.video.create(params) - Create a new video generation jobclient.video.status(videoId) - Check the status of a video generation jobclient.journals.list(pageToken?) - List all journals with optional paginationclient.journals.content(journalId) - Get the content of a specific journalAll API methods may throw errors. It's recommended to wrap API calls in try-catch blocks:
try {
const response = await client.video.create(params);
// Handle success
} catch (error) {
console.error('API Error:', error);
// Handle error
}
Store your API key securely using environment variables:
export OPENNOTE_API_KEY="your_api_key_here"
Check out the examples directory for complete working examples:
FAQs
Opennote TypeScript SDK
We found that @opennote-ed/sdk 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.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.