Chaindoc SDK
Chaindoc пропонує два TypeScript SDK: Server SDK для роботи на бекенді (Node.js) та Embed SDK для вбудовування інтерфейсу підписування у ваш веб-застосунок. Обидва мають повні типи, нуль залежностей під час виконання та працюють з будь-яким фреймворком.
Доступні SDK
Для налаштування npm та конфігурації під конкретний фреймворк (змінні середовища, провайдери тощо) дивіться посібник з встановлення.
- Server SDK (@chaindoc_io/server-sdk) — інтеграція бекенду для Node.js 18+
- Embed SDK (@chaindoc_io/embed-sdk) — інтерфейс підписування для веб-застосунків
- Python SDK — з'явиться незабаром
- PHP SDK — з'явиться незабаром
Server SDK
Server SDK обгортає REST API у типобезпечний інтерфейс Node.js. Використовуйте його для керування документами, створення запитів на підпис, обробки завантажень файлів та запуску блокчейн-верифікації.
Встановлення
npm install @chaindoc_io/server-sdkШвидкий старт
import { Chaindoc } from '@chaindoc_io/server-sdk';
import { readFile } from 'fs/promises';
// 1. Ініціалізуйте SDK
const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
});
// 2. Завантажте файл документа
const buffer = await readFile('./contract.pdf');
const file = new Blob([buffer], { type: 'application/pdf' });
const { media } = await chaindoc.media.upload([file]);
// 3. Створіть документ
const doc = await chaindoc.documents.create({
name: 'Service Agreement',
description: 'Contract for consulting services',
media: media[0],
status: 'published', // Запускає блокчейн-верифікацію
hashtags: ['#contract', '#2024'],
meta: [{ key: 'client', value: 'Acme Corp' }],
});
// 4. Створіть запит на підпис
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. Створіть сесію для фронтенд 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
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!,
});
// Завантаження та створення документа
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' });
}
}
});
// Створення вбудованої сесії для підписанта
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);API маршрути Next.js
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 }
);
}
}Обробка помилок
Завжди обгортайте виклики API у try-catch блоки та обробляйте ChaindocError окремо:
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:
// Неправильний запит — перевірте параметри
break;
case 401:
// Неавторизовано — перевірте API ключ
break;
case 404:
// Не знайдено
break;
case 429:
// Ліміт запитів — SDK автоматично повторить
break;
}
}
}Embed SDK
Embed SDK дозволяє показувати інтерфейс підписування Chaindoc прямо у вашому веб-застосунку. Він керує iframe, OTP-верифікацією та комунікацією між вашим застосунком і Chaindoc. Ваші користувачі підписують документи, не залишаючи ваш сайт.
Встановлення
npm install @chaindoc_io/embed-sdkБазове використання
import { ChaindocEmbed } from '@chaindoc_io/embed-sdk';
// 1. Ініціалізуйте SDK (один раз на сторінку)
const chaindoc = new ChaindocEmbed({
publicKey: 'pk_live_xxxxxxxxxxxxx',
environment: 'production',
});
// 2. Отримайте сесію з вашого бекенду
const response = await fetch('/api/signing/create-session', {
method: 'POST',
body: JSON.stringify({ documentId, signerEmail }),
});
const { sessionId } = await response.json();
// 3. Відкрийте процес підписування
const instance = chaindoc.openSignatureFlow({
sessionId,
onReady: () => {
console.log('Інтерфейс підписування завантажено');
},
onSuccess: (data) => {
console.log('Документ підписано:', data.signatureId);
instance.close();
},
onError: (error) => {
console.error('Помилка підписання:', error.code, error.message);
},
onCancel: () => {
console.log('Користувач скасував');
instance.close();
},
});Інтеграція з React
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('Підписано!', data.signatureId);
instanceRef.current?.close();
},
onCancel: () => {
instanceRef.current?.close();
},
});
}, [sessionId]);
return <button onClick={handleSign}>Підписати документ</button>;
}Інтеграція з Vue 3
<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('Підписано!', data.signatureId);
instance?.close();
},
onCancel: () => {
instance?.close();
},
});
}
</script>
<template>
<button @click="openSignature">Підписати документ</button>
</template>Вбудований режим
Замість модального вікна вбудуйте інтерфейс підписування прямо на сторінку:
const instance = chaindoc.openSignatureFlow({
sessionId,
mode: 'inline',
container: document.getElementById('signature-container'),
onSuccess: (data) => {
console.log('Підписано!');
},
});Темізація
Налаштуйте зовнішній вигляд світлими або темними темами:
const instance = chaindoc.openSignatureFlow({
sessionId,
theme: 'dark',
// ... інші опції
});
// Змініть тему динамічно
instance.changeTheme('light');Повний приклад робочого процесу
Ось у чому справа: Server SDK на бекенді створює документи та сесії, Embed SDK на фронтенді показує інтерфейс підписування. Чесно кажучи, це найзручніший спосіб інтеграції.
1Бекенд: завантаження документаВикористовуйте Server SDK для завантаження файлу та створення документа
2Бекенд: створення запиту на підписСтворіть запит на підпис з увімкненим вбудованим потоком
3Бекенд: генерація сесіїСтворіть вбудовану сесію для кожного підписанта
4Фронтенд: ініціалізація Embed SDKІніціалізуйте SDK з публічним ключем
5Фронтенд: відкриття процесу підписуванняВідкрийте інтерфейс підписування з ID сесії
6Фронтенд: обробка успіхуОбробіть підписаний документ та оновіть інтерфейс
// server.ts
import { Chaindoc } from '@chaindoc_io/server-sdk';
const chaindoc = new Chaindoc({
secretKey: process.env.CHAINDOC_SECRET_KEY!,
});
// Завантаження та створення документа
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: [],
});
// Створення запиту на підпис
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,
});
// Створення сесії
const session = await chaindoc.embedded.createSession({
email: 'signer@example.com',
metadata: {
documentId: doc.documentId,
signatureRequestId: sigRequest.signatureRequest.uuid,
},
});
// Поверніть sessionId на фронтенд
res.json({ sessionId: session.sessionId });Кращі практики
- Ініціалізуйте SDK один раз за життєвий цикл сторінки/компонента
- Завжди знищуйте екземпляр SDK при розмонтуванні компонента
- Обробляйте всі callback-події (onSuccess, onError, onCancel)
- Зберігайте API ключі в змінних середовища
- Використовуйте TypeScript для кращої типобезпечності
- Реалізуйте належну обробку помилок з ChaindocError
- Тестуйте з sandbox ключами перед production розгортанням
Конфігурація середовища
// Backend
const chaindoc = new Chaindoc({
secretKey: 'sk_live_xxxxx',
});
// Frontend
const embed = new ChaindocEmbed({
publicKey: 'pk_live_xxxxx',
environment: 'production',
});Що робити далі
- Встановлення — налаштування npm, конфігурація середовища та провайдери під конкретні фреймворки
- API документація — повний довідник REST ендпоінтів
- Webhooks — сповіщення про події в реальному часі для вашого бекенду
- Швидкий старт — надішліть ваш перший підпис за 10 хвилин
- Безпека — керування API ключами та харднінг production