Official JavaScript/TypeScript SDK for ProofChain - blockchain-anchored document attestation
npm install @proofchain/sdkOfficial JavaScript/TypeScript SDK for ProofChain - blockchain-anchored document attestation.
Works in Node.js and browsers.
``bash`
npm install @proofchain/sdkor
yarn add @proofchain/sdkor
pnpm add @proofchain/sdk
`typescript
import { ProofChain } from '@proofchain/sdk';
// Create client
const client = new ProofChain({ apiKey: 'your-api-key' });
// Attest a document
const result = await client.documents.attest({
file: myFile, // File, Blob, or Buffer
userId: 'user@example.com',
eventType: 'contract_signed',
});
console.log('IPFS Hash:', result.ipfsHash);
console.log('Verify URL:', result.verifyUrl);
// Verify
const verification = await client.verify(result.ipfsHash);
console.log('Valid:', verification.valid);
`
For maximum throughput, use the dedicated IngestionClient which connects directly to the Rust ingestion API:
`typescript
import { IngestionClient } from '@proofchain/sdk';
const ingestion = new IngestionClient({ apiKey: 'your-api-key' });
// Single event (immediate attestation)
const result = await ingestion.ingest({
userId: 'user-123',
eventType: 'purchase',
data: { amount: 99.99, product: 'widget' },
});
console.log('Event ID:', result.eventId);
console.log('Certificate:', result.certificateId);
// Batch events (up to 1000 per request)
const batchResult = await ingestion.ingestBatch({
events: [
{ userId: 'user-1', eventType: 'click', data: { page: '/home' } },
{ userId: 'user-2', eventType: 'click', data: { page: '/products' } },
// ... up to 1000 events
],
});
console.log('Queued:', batchResult.queued);
console.log('Failed:', batchResult.failed);
`
For high-throughput scenarios (100K+ events/sec):
`typescript
import { ProofChain } from '@proofchain/sdk';
const client = new ProofChain({ apiKey: 'your-api-key' });
// Create a state channel
const channel = await client.channels.create({ name: 'iot-sensors' });
// Stream events
for (const reading of sensorReadings) {
await client.channels.stream(channel.channelId, {
eventType: 'sensor_reading',
userId: reading.deviceId,
data: { temperature: reading.temp, humidity: reading.humidity },
});
}
// Settle on-chain
const settlement = await client.channels.settle(channel.channelId);
console.log('TX Hash:', settlement.txHash);
`
`typescript
// Attest a file (Node.js)
import { readFileSync } from 'fs';
const result = await client.documents.attest({
file: readFileSync('contract.pdf'),
filename: 'contract.pdf',
userId: 'user@example.com',
eventType: 'document_uploaded',
metadata: { department: 'legal' },
});
// Attest a file (Browser)
const fileInput = document.querySelector('input[type="file"]');
const result = await client.documents.attest({
file: fileInput.files[0],
userId: 'user@example.com',
});
// Get document by hash
const doc = await client.documents.get('Qm...');
`
`typescript
// Create an event
const event = await client.events.create({
eventType: 'user_action',
userId: 'user123',
data: { action: 'login', ip: '192.168.1.1' },
});
// List events
const events = await client.events.list({
userId: 'user123',
eventType: 'user_action',
limit: 100,
});
// Search events
const results = await client.events.search({
query: 'login',
startDate: '2024-01-01',
endDate: '2024-12-31',
});
`
`typescript
// Verify by IPFS hash
const result = await client.verify('Qm...');
if (result.valid) {
console.log('Timestamp:', result.timestamp);
console.log('Blockchain TX:', result.blockchainTx);
console.log('Certificate ID:', result.certificateId);
}
`
`typescript
// Issue a certificate
const cert = await client.certificates.issue({
recipientName: 'John Doe',
recipientEmail: 'john@example.com',
title: 'Course Completion',
description: 'Completed JavaScript Fundamentals',
metadata: { courseId: 'JS101', score: 95 },
});
console.log('Certificate ID:', cert.certificateId);
console.log('QR Code:', cert.qrCodeUrl);
// Revoke
await client.certificates.revoke(cert.certificateId, 'Issued in error');
`
`typescript
// Register a webhook
const webhook = await client.webhooks.create({
url: 'https://your-app.com/webhook',
events: ['document.attested', 'channel.settled'],
secret: 'your-secret',
});
// List webhooks
const webhooks = await client.webhooks.list();
// Delete
await client.webhooks.delete(webhook.id);
`
Quests are gamified user journeys with steps that can be completed via events.
`typescript
// List available quests for a user (with their progress)
const quests = await client.quests.listAvailable(userId);
// Returns: { quest: Quest, progress?: UserQuestProgress }[]
// Each quest has a type that determines behavior:
// - 'epic': Long-form quests - user must explicitly start
// - 'quick_hit': Short quests - auto-enrolls on matching event
// - 'challenge': Time-limited quests - auto-enrolls on matching event
for (const { quest, progress } of quests) {
console.log(${quest.name} (${quest.quest_type})); Progress: ${progress.completion_percentage}%
if (progress) {
console.log();
}
}
// Start an Epic quest (required for epic type only)
const progress = await client.quests.startQuest(questId, userId);
// Get user's progress on a specific quest
const questProgress = await client.quests.getUserProgress(questId, userId);
// Get all quest progress for a user
const allProgress = await client.quests.getAllUserProgress(userId);
// Complete a step manually (for manual step types)
const result = await client.quests.completeStep(questId, userId, stepIndex);
console.log('Step completed:', result.step_completed);
console.log('Quest completed:', result.quest_completed);
`
Quest Types:
| Type | Behavior |
|------|----------|
| epic | Long-form, multi-step quests. User must call startQuest() to begin. |quick_hit
| | Short, easy quests. Auto-enrolls when user triggers a matching event. |challenge
| | Time-limited or competitive. Auto-enrolls when user triggers a matching event. |
`typescript
import { ProofChain, ProofChainError, AuthenticationError, RateLimitError } from '@proofchain/sdk';
try {
const result = await client.documents.attest(req);
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key');
} else if (error instanceof RateLimitError) {
console.error(Rate limited. Retry after ${error.retryAfter} seconds);API error: ${error.message}
} else if (error instanceof ProofChainError) {
console.error();`
}
}
`typescript
import { ProofChain } from '@proofchain/sdk';
// Full configuration
const client = new ProofChain({
apiKey: 'your-api-key',
baseUrl: 'https://ingest.proofchain.co.za', // Ingestion API (Rust)
mgmtUrl: 'https://api.proofchain.co.za', // Management API (Python)
timeout: 30000, // 30 seconds
maxRetries: 3,
});
// From environment variable (Node.js)
// Set PROOFCHAIN_API_KEY
const client = ProofChain.fromEnv();
`
Full TypeScript support with exported types:
`typescript`
import type {
AttestationResult,
Event,
Channel,
ChannelStatus,
Settlement,
Certificate,
Webhook,
VerificationResult,
SearchResult,
} from '@proofchain/sdk';
The SDK works in browsers with no additional configuration:
`html``
MIT License - see LICENSE for details.
- Documentation: https://proofchain.co.za/docs
- Email: support@proofchain.co.za
- GitHub Issues: https://github.com/proofchain/proofchain-js/issues