Chaindoc SDK'ları
Chaindoc iki adet TypeScript SDK sunuyor. Server SDK backend işlemleri için (Node.js), Embed SDK ise web uygulamanıza entegre imzalama arayüzü sağlıyor. İkisinde de tam tip tanımları mevcut, runtime bağımlılığı yok, istediğiniz framework ile çalışıyor.
Mevcut SDK'lar
npm kurulumu ve framework-spesifik yapılandırma (environment değişkenleri, provider'lar vb.) için kurulum rehberine bakabilirsiniz.
- Server SDK (@chaindoc_io/server-sdk) - Node.js 18+ için backend entegrasyonu
- Embed SDK (@chaindoc_io/embed-sdk) - Web uygulamaları için frontend imzalama arayüzü
- Python SDK - Çok yakında
- PHP SDK - Çok yakında
Server SDK
Server SDK, REST API'yi tip-güvenli bir Node.js arayüzüne sarıyor. Doküman yönetimi, imza istekleri oluşturma, dosya yükleme ve blockchain doğrulama işlemlerinde kullanıyorsunuz.
Kurulum
npm install @chaindoc_io/server-sdkHızlı başlangıç
import { Chaindoc } from '@chaindoc_io/server-sdk';
import { readFile } from 'fs/promises';
// 1. Initialize the SDK
const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
});
// 2. Upload a document file
const buffer = await readFile('./contract.pdf');
const file = new Blob([buffer], { type: 'application/pdf' });
const { media } = await chaindoc.media.upload([file]);
// 3. Create a document
const doc = await chaindoc.documents.create({
name: 'Service Agreement',
description: 'Contract for consulting services',
media: media[0],
status: 'published', // Triggers blockchain verification
hashtags: ['#contract', '#2024'],
meta: [{ key: 'client', value: 'Acme Corp' }],
});
// 4. Create a signature request
const sigRequest = await chaindoc.signatures.createRequest({
versionId: doc.document.versions[0].uuid,
recipients: [{ email: 'signer@example.com' }],
deadline: new Date('2024-12-31'),
embeddedFlow: true,
});
// 5. Create session for frontend SDK
const session = await chaindoc.embedded.createSession({
email: 'signer@example.com',
metadata: {
documentId: doc.documentId,
signatureRequestId: sigRequest.signatureRequest.uuid,
},
});
console.log('Session ID:', session.sessionId);Express.js Entegrasyonu
import express from 'express';
import { Chaindoc, ChaindocError } from '@chaindoc_io/server-sdk';
import multer from 'multer';
const app = express();
const upload = multer({ storage: multer.memoryStorage() });
const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
});
// Upload and create document
app.post('/api/documents', upload.single('file'), async (req, res) => {
try {
const file = new Blob([req.file!.buffer], { type: req.file!.mimetype });
const { media } = await chaindoc.media.upload([file]);
const doc = await chaindoc.documents.create({
name: req.body.name,
description: req.body.description || '',
media: media[0],
status: 'published',
hashtags: req.body.hashtags || [],
meta: req.body.meta || [],
});
res.json({ documentId: doc.documentId });
} catch (error) {
if (error instanceof ChaindocError) {
res.status(error.statusCode || 500).json({ error: error.message });
} else {
res.status(500).json({ error: 'Internal server error' });
}
}
});
// Create embedded session for signer
app.post('/api/signing/session', async (req, res) => {
try {
const { email, documentId, signatureRequestId } = req.body;
const session = await chaindoc.embedded.createSession({
email,
metadata: { documentId, signatureRequestId },
});
res.json({ sessionId: session.sessionId });
} catch (error) {
if (error instanceof ChaindocError) {
res.status(error.statusCode || 500).json({ error: error.message });
}
}
});
app.listen(3000);Next.js API Routes
import { NextRequest, NextResponse } from 'next/server';
import { Chaindoc, ChaindocError } from '@chaindoc_io/server-sdk';
const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
});
export async function POST(request: NextRequest) {
try {
const { email, documentId, signatureRequestId } = await request.json();
const session = await chaindoc.embedded.createSession({
email,
metadata: { documentId, signatureRequestId },
});
return NextResponse.json({
sessionId: session.sessionId,
expiresAt: session.expiresAt,
});
} catch (error) {
if (error instanceof ChaindocError) {
return NextResponse.json(
{ error: error.message },
{ status: error.statusCode || 500 }
);
}
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}Hata yönetimi
API çağrılarını mutlaka try-catch blokları içine alın, ChaindocError'u özel olarak ele alın:
import { ChaindocError } from '@chaindoc_io/server-sdk';
try {
const doc = await chaindoc.documents.create({ /* ... */ });
} catch (error) {
if (error instanceof ChaindocError) {
console.error('API Error:', error.message);
console.error('Status Code:', error.statusCode);
switch (error.statusCode) {
case 400:
// Bad request - check parameters
break;
case 401:
// Unauthorized - check API key
break;
case 404:
// Not found
break;
case 429:
// Rate limited - SDK will auto-retry
break;
}
}
}Embed SDK
Embed SDK, Chaindoc imzalama arayüzünü web uygulamanızın içinde göstermenizi sağlıyor. iframe yönetimi, OTP doğrulama ve uygulamanız ile Chaindoc arasındaki iletişimi hallediyor. Kullanıcılarınız sitenizden ayrılmadan doküman imzalıyor.
Kurulum
npm install @chaindoc_io/embed-sdkTemel kullanım
import { ChaindocEmbed } from '@chaindoc_io/embed-sdk';
// 1. Initialize SDK (once per page)
const chaindoc = new ChaindocEmbed({
publicKey: 'pk_live_xxxxxxxxxxxxx',
environment: 'production',
});
// 2. Get session from your backend
const response = await fetch('/api/signing/create-session', {
method: 'POST',
body: JSON.stringify({ documentId, signerEmail }),
});
const { sessionId } = await response.json();
// 3. Open signing flow
const instance = chaindoc.openSignatureFlow({
sessionId,
onReady: () => {
console.log('Signing interface loaded');
},
onSuccess: (data) => {
console.log('Document signed:', data.signatureId);
instance.close();
},
onError: (error) => {
console.error('Signing failed:', error.code, error.message);
},
onCancel: () => {
console.log('User cancelled');
instance.close();
},
});React entegrasyonu
import { useCallback, useRef, useEffect } from 'react';
import { ChaindocEmbed, EmbedInstance } from '@chaindoc_io/embed-sdk';
function SignButton({ sessionId }: { sessionId: string }) {
const sdkRef = useRef<ChaindocEmbed | null>(null);
const instanceRef = useRef<EmbedInstance | null>(null);
useEffect(() => {
sdkRef.current = new ChaindocEmbed({
publicKey: process.env.REACT_APP_CHAINDOC_PUBLIC_KEY!,
});
return () => {
sdkRef.current?.destroy();
};
}, []);
const handleSign = useCallback(() => {
if (!sdkRef.current) return;
instanceRef.current = sdkRef.current.openSignatureFlow({
sessionId,
onSuccess: (data) => {
console.log('Signed!', data.signatureId);
instanceRef.current?.close();
},
onCancel: () => {
instanceRef.current?.close();
},
});
}, [sessionId]);
return <button onClick={handleSign}>Sign Document</button>;
}Vue 3 entegrasyonu
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { ChaindocEmbed, type EmbedInstance } from '@chaindoc_io/embed-sdk';
const props = defineProps<{ sessionId: string }>();
let sdk: ChaindocEmbed | null = null;
let instance: EmbedInstance | null = null;
onMounted(() => {
sdk = new ChaindocEmbed({
publicKey: import.meta.env.VITE_CHAINDOC_PUBLIC_KEY,
});
});
onUnmounted(() => {
sdk?.destroy();
});
function openSignature() {
if (!sdk) return;
instance = sdk.openSignatureFlow({
sessionId: props.sessionId,
onSuccess: (data) => {
console.log('Signed!', data.signatureId);
instance?.close();
},
onCancel: () => {
instance?.close();
},
});
}
</script>
<template>
<button @click="openSignature">Sign Document</button>
</template>Inline mod
Modal yerine imzalama arayüzünü sayfanızın içine doğrudan gömebilirsiniz:
const instance = chaindoc.openSignatureFlow({
sessionId,
mode: 'inline',
container: document.getElementById('signature-container'),
onSuccess: (data) => {
console.log('Signed!');
},
});Tema özelleştirme
Light veya dark tema ile görünümü özelleştirin:
const instance = chaindoc.openSignatureFlow({
sessionId,
theme: 'dark',
// ... other options
});
// Change theme dynamically
instance.changeTheme('light');Tam iş akışı örneği
Şimdi her iki SDK'yi bir araya getirelim. Backend'de Server SDK ile doküman ve session oluşturuyoruz, frontend'de Embed SDK ile imzalama UI gösteriyoruz.
1Backend: Doküman YüklemeServer SDK ile dosya yükleme ve doküman oluşturma
2Backend: İmza İsteği OluşturmaEmbedded flow aktif olarak imza isteği oluşturma
3Backend: Session ÜretmeHer imzacı için embedded session oluşturma
4Frontend: Embed SDK BaşlatmaPublic key ile SDK'yi başlatma
5Frontend: İmza Akışını AçmaSession ID ile imzalama arayüzünü açma
6Frontend: Başarıyı İşlemeİmzalanan dokümanı işleme ve UI güncelleme
// server.ts
import { Chaindoc } from '@chaindoc_io/server-sdk';
const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
});
// Upload & create document
const { media } = await chaindoc.media.upload([pdfFile]);
const doc = await chaindoc.documents.create({
name: 'Contract',
description: 'Service agreement',
media: media[0],
status: 'published',
hashtags: ['#contract'],
meta: [],
});
// Create signature request
const sigRequest = await chaindoc.signatures.createRequest({
versionId: doc.document.versions[0].uuid,
recipients: [{ email: 'signer@example.com' }],
deadline: new Date('2024-12-31'),
embeddedFlow: true,
});
// Create session
const session = await chaindoc.embedded.createSession({
email: 'signer@example.com',
metadata: {
documentId: doc.documentId,
signatureRequestId: sigRequest.signatureRequest.uuid,
},
});
// Return sessionId to frontend
res.json({ sessionId: session.sessionId });En iyi uygulamalar
- Sayfa veya component lifecycle başına SDK'yi bir kez başlatın
- Component unmount olduğunda SDK instance'ını mutlaka destroy edin
- Tüm callback eventlerini ele alın (onSuccess, onError, onCancel)
- API key'leri environment değişkenlerinde saklayın
- Daha iyi tip güvenliği için TypeScript kullanın
- ChaindocError ile düzgün hata yönetimi uygulayın
- Production deployment öncesi sandbox key'lerle test edin
Ortam yapılandırması
// Backend
const chaindoc = new Chaindoc({
secretKey: 'sk_live_xxxxx',
});
// Frontend
const embed = new ChaindocEmbed({
publicKey: 'pk_live_xxxxx',
environment: 'production',
});Sırada ne var
- Kurulum — npm kurulumu, env yapılandırması ve framework-spesifik provider'lar
- API dokümantasyonu — tam REST endpoint referansı
- Webhooks — backend'iniz için gerçek zamanlı event bildirimleri
- Hızlı başlangıç — 10 dakikada ilk imzanızı gönderin
- Güvenlik — API key yönetimi ve production hardening