{"_rev":"4-bda1d5dcf031f9e1f19372ec2316e2bd","time":{"created":"2026-06-01T07:47:14.161Z","modified":"2026-06-01T07:47:14.825Z","0.1.0":"2022-05-02T22:37:42.357Z","1.0.0":"2022-05-10T03:35:36.398Z","2.4.0":"2026-06-01T07:47:14.521Z"},"_id":"@anchora/sdk","name":"@anchora/sdk","dist-tags":{"latest":"2.4.0"},"versions":{"2.4.0":{"name":"@anchora/sdk","version":"2.4.0","description":"Official JavaScript SDK for Anchora VaaS - Blockchain Data Anchoring Platform (with Hybrid API v2.0, Key Management)","main":"src/index.js","module":"src/index.mjs","types":"src/index.d.ts","exports":{".":{"import":"./src/index.mjs","require":"./src/index.js","types":"./src/index.d.ts"}},"keywords":["anchora","blockchain","verification","vaas","data-integrity","tamper-proof","merkle-tree","polygon","e2e-encryption","key-management","x3dh"],"author":{"name":"Anchora Team","email":"vigneshwaran.bs@anchora.co.in"},"license":"MIT","homepage":"https://github.com/anchora-labs/anchora-sdk-js#readme","repository":{"type":"git","url":"git+https://github.com/anchora-labs/anchora-sdk-js.git"},"bugs":{"url":"https://github.com/anchora-labs/anchora-sdk-js/issues","email":"vigneshwaran.bs@anchora.co.in"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"engines":{"node":">=14.0.0"},"scripts":{"test":"node tests/parity.test.cjs","prepublishOnly":"echo 'Ready to publish @anchora/sdk v2.4.0'"},"dependencies":{"@noble/curves":"^1.9.7","axios":"^1.16.0","form-data":"^4.0.5"},"gitHead":"b48bdc16e9568fa8444034e1563d71a7fb537218","_id":"@anchora/sdk@2.4.0","_nodeVersion":"25.6.1","_npmVersion":"11.9.0","dist":{"integrity":"sha512-TScdn6obFITMXz8bGbX7cQaG2kmd6V7NvyG02whvIYdXzUaO7OZuHRKN/bVHyXF3MgVcvka5qK9dPJkNWI46Ww==","shasum":"a2a8d05580d864e2000403ac39b8171031c2c610","tarball":"https://registry.npmjs.org/@anchora/sdk/-/sdk-2.4.0.tgz","fileCount":12,"unpackedSize":107510,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDvAZ3aTldTsmQyqAng9PC5KW2f2P2wdX8JW99eiIaiIgIhAOAwj14+yVXyUlXog+FBPmPShwEK/yIaok4ietMuqXj4"}]},"_npmUser":{"name":"anchora_labs","email":"vigneshwaran.bs@anchora.co.in"},"directories":{},"maintainers":[{"name":"anchora_labs","email":"vigneshwaran.bs@anchora.co.in"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_2.4.0_1780300034364_0.44066428856330564"},"_hasShrinkwrap":false}},"maintainers":[{"name":"anchora_labs","email":"vigneshwaran.bs@anchora.co.in"}],"description":"Official JavaScript SDK for Anchora VaaS - Blockchain Data Anchoring Platform (with Hybrid API v2.0, Key Management)","homepage":"https://github.com/anchora-labs/anchora-sdk-js#readme","keywords":["anchora","blockchain","verification","vaas","data-integrity","tamper-proof","merkle-tree","polygon","e2e-encryption","key-management","x3dh"],"repository":{"type":"git","url":"git+https://github.com/anchora-labs/anchora-sdk-js.git"},"author":{"name":"Anchora Team","email":"vigneshwaran.bs@anchora.co.in"},"bugs":{"url":"https://github.com/anchora-labs/anchora-sdk-js/issues","email":"vigneshwaran.bs@anchora.co.in"},"license":"MIT","readme":"# Anchora SDK\n\n[![npm version](https://img.shields.io/npm/v/@anchora/sdk.svg)](https://www.npmjs.com/package/@anchora/sdk)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Node](https://img.shields.io/node/v/@anchora/sdk.svg)](https://nodejs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-supported-blue.svg)](https://www.typescriptlang.org/)\n\nOfficial JavaScript / TypeScript SDK for [**Anchora**](https://www.anchora.co.in) — anchor any data hash to the Polygon blockchain, verify integrity later, and detect tampering with zero data exposure.\n\nBuilt for developers shipping audit-grade, tamper-evident records in healthcare, finance, supply chain, document verification, and any domain where data integrity matters more than storage.\n\n## Installation\n\n```bash\nnpm install @anchora/sdk\n```\n\n> **Requires Node.js 14+.** Works in modern browsers and Node.js. TypeScript types are bundled — no `@types/*` package needed.\n\n## Quick Start\n\n```javascript\nconst { AnchoraClient } = require('@anchora/sdk');\n\n// Initialize client\nconst anchora = new AnchoraClient({\n  apiKey: 'your-api-key',\n  projectId: 'your-project-id'\n});\n\n// Anchor data to blockchain\nconst result = await anchora.anchor({\n  orderId: 'ORD-12345',\n  total: 999.99,\n  timestamp: Date.now()\n});\n\nconsole.log('Data anchored:', result.hash);\n```\n\n## Features\n\n- ✅ **Hash-only mode** — anchor a SHA-256 hash without sending your data anywhere (the most private and recommended mode)\n- ✅ **Blockchain proof** — every record is provably anchored on Polygon, batched via Merkle tree for ~$0.000007 per record\n- ✅ **Canonical hashing** — deterministic SHA-256 over JSON (byte-identical to the server)\n- ✅ **AES-256-GCM encryption** — built-in with PBKDF2 key derivation (100k iterations) when you need to store data\n- ✅ **File support** — upload + hash + verify documents (PDF, images, DOCX, etc.) up to 50MB\n- ✅ **Batch operations** — anchor up to 100 records in a single API call\n- ✅ **Tamper detection** — verify on read; mismatches throw with a clear error\n- ✅ **Webhook callbacks** — get notified when batches are anchored on-chain\n- ✅ **Auto-retry** — exponential backoff on transient failures\n- ✅ **TypeScript types** — full `.d.ts` bundled\n- ✅ **Audited cryptography** — uses [`@noble/curves`](https://github.com/paulmillr/noble-curves) for X25519 / Ed25519 (Signal-style key management)\n\n## Use cases\n\n- **Tamper-evident audit logs** — anchor every record write; prove later that history wasn't rewritten\n- **Document authenticity** — university certificates, medical reports, legal contracts (verify with a single hash)\n- **Supply chain integrity** — anchor shipment milestones; prove provenance at delivery\n- **Regulatory compliance** — immutable, third-party-verifiable record of what happened when\n\n## Configuration\n\n```javascript\nconst anchora = new AnchoraClient({\n  apiKey: 'dcp_live_...',           // Required: Your API key\n  projectId: 'proj_...',             // Optional: Project ID\n  baseURL: 'https://api.anchora.co.in', // Optional: Custom API URL (defaults to production)\n  timeout: 30000,                    // Optional: Request timeout (ms)\n  retries: 3,                        // Optional: Number of retries\n  retryDelay: 1000                   // Optional: Retry delay (ms)\n});\n```\n\n## Core Methods\n\n### anchor(data, options)\n\nAnchor data to the blockchain. The Anchora API computes the hash automatically.\n\n**Traditional Mode (Default)** - Stores data in Anchora:\n```javascript\nconst result = await anchora.anchor(\n  {\n    userId: 'user-123',\n    action: 'purchase',\n    amount: 50.00\n  },\n  {\n    metadata: { source: 'web-app' },\n    webhookUrl: 'https://yourapp.com/webhook',  // Optional: Get notified when anchored\n    hashOnly: false  // Default: stores data in Anchora\n  }\n);\n\n// Returns:\n// {\n//   success: true,\n//   message: 'Hash queued for anchoring',\n//   hash: '3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b',\n//   recordId: 'rec_...',\n//   status: 'QUEUED',\n//   hashOnly: false,\n//   estimatedAnchorTime: '30 seconds',\n//   queuedAt: '2025-11-28T10:30:00.000Z'\n// }\n```\n\n**Hash-Only Mode** - Maximum privacy, no data stored in Anchora:\n```javascript\nconst result = await anchora.anchor(\n  {\n    certificateId: 'CERT-2025-001',\n    studentName: 'John Doe',\n    course: 'Computer Science'\n  },\n  {\n    collection: 'certificates',\n    hashOnly: true  // ← Only hash stored, not data\n  }\n);\n\n// Returns:\n// {\n//   success: true,\n//   message: 'Hash queued for anchoring',\n//   hash: 'abc123...',\n//   recordId: 'rec_...',\n//   status: 'QUEUED',\n//   hashOnly: true,\n//   note: 'Hash-only mode: Data not stored, only hash anchored to blockchain',\n//   estimatedAnchorTime: '30 seconds',\n//   queuedAt: '2025-11-28T10:30:00.000Z'\n// }\n\n// YOU MUST store the data in YOUR database:\nawait db.collection('certificates').insertOne({\n  certificateId: 'CERT-2025-001',\n  studentName: 'John Doe',\n  course: 'Computer Science',\n  vaas: {\n    hash: result.hash,\n    recordId: result.recordId\n  }\n});\n```\n\n### verify(data, options)\n\nVerify data integrity against blockchain. Computes hash and checks for tampering.\n\n```javascript\n// Basic verification (checks hash only)\nconst result = await anchora.verify({\n  userId: 'user-123',\n  action: 'purchase',\n  amount: 50.00\n});\n\n// Full verification (with Merkle proof)\nconst result = await anchora.verify(\n  {\n    userId: 'user-123',\n    action: 'purchase',\n    amount: 50.00\n  },\n  {\n    hash: 'e3b0c442...',  // Expected hash\n    blockNumber: 29496609,  // Block number\n    merkleProof: ['0x123...', '0xabc...']  // Merkle proof\n  }\n);\n\n// Returns (if verified):\n// {\n//   success: true,\n//   verified: true,\n//   status: 'VERIFIED',\n//   message: 'Data integrity verified with Merkle proof',\n//   hash: '3a7bd3e2...',\n//   blockNumber: 29496609,\n//   merkleRoot: '0x9876...',\n//   verifiedAt: '2025-11-28T10:30:00.000Z'\n// }\n\n// Returns (if tampered):\n// {\n//   success: false,\n//   verified: false,\n//   status: 'TAMPERED',\n//   message: 'Data has been modified. Hash mismatch.',\n//   providedHash: 'e3b0c442...',\n//   computedHash: 'd7a8fbb3...'\n// }\n```\n\n### getProof(hash)\n\nGet blockchain proof for a hash.\n\n```javascript\nconst proof = await anchora.getProof('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');\n\n// Returns:\n// {\n//   success: true,\n//   hash: 'e3b0c442...',\n//   status: 'ANCHORED',\n//   proof: {\n//     blockNumber: 29496609,\n//     transactionHash: '0xb706858a...',\n//     merkleProof: ['0x1234...', '0xabcd...'],\n//     batchId: 30,\n//     anchoredAt: '2025-11-25T10:00:30Z'\n//   },\n//   metadata: {\n//     recordType: 'invoice'\n//   }\n// }\n```\n\n### getBatch(batchId)\n\nGet batch information.\n\n```javascript\nconst result = await anchora.getBatch(30);\n\n// Returns:\n// {\n//   success: true,\n//   batch: {\n//     batchId: 30,\n//     merkleRoot: '0x9876543210fedcba...',\n//     recordCount: 256,\n//     actualRecordCount: 256,\n//     blockNumber: 29496609,\n//     transactionHash: '0xb706858a2c9e4a8e3d5f9c1a2b3d4e5f...',\n//     gasUsed: 118330,\n//     cost: 0.0018,\n//     status: 'ANCHORED',\n//     anchoredAt: '2025-11-25T10:00:30Z',\n//     createdAt: '2025-11-25T10:00:00Z'\n//   }\n// }\n```\n\n### anchorBatch(records, options)\n\nAnchor multiple records at once (up to 100 records per batch). Efficient for bulk operations.\n\n```javascript\n// Basic batch anchoring\nconst result = await anchora.anchorBatch([\n  {\n    data: { orderId: 'ORD-001', total: 100.00 },\n    collection: 'orders',\n    metadata: { source: 'web-app' }\n  },\n  {\n    data: { orderId: 'ORD-002', total: 250.00 },\n    collection: 'orders'\n  },\n  {\n    data: { orderId: 'ORD-003', total: 75.50 },\n    collection: 'orders'\n  }\n], {\n  webhookUrl: 'https://yourapp.com/webhook/batch'  // Optional: Single webhook for all\n});\n\n// Returns:\n// {\n//   success: true,\n//   message: 'Batch anchoring completed',\n//   batchId: 'batch_1735131234567_abc123',\n//   totalRecords: 3,\n//   results: [\n//     {\n//       success: true,\n//       index: 0,\n//       recordId: 'rec_xyz1',\n//       hash: 'abc123...',\n//       status: 'QUEUED',\n//       collection: 'orders',\n//       encrypted: false\n//     },\n//     // ... more results\n//   ],\n//   summary: {\n//     successful: 3,\n//     failed: 0\n//   }\n// }\n```\n\n**Batch with encryption:**\n```javascript\nconst result = await anchora.anchorBatch([\n  {\n    data: { patientId: 'P-001', diagnosis: 'Diabetes' },\n    collection: 'medical',\n    encrypt: true,\n    encryptionKey: anchora.generateEncryptionKey(32)\n  },\n  {\n    data: { patientId: 'P-002', diagnosis: 'Hypertension' },\n    collection: 'medical',\n    encrypt: true,\n    encryptionKey: anchora.generateEncryptionKey(32)\n  }\n]);\n```\n\n**Mixed batch (encrypted + plain + hash-only):**\n```javascript\nconst result = await anchora.anchorBatch([\n  {\n    data: { invoiceId: 'INV-001', amount: 1000 },\n    collection: 'invoices'\n  },\n  {\n    data: { ssn: '123-45-6789', name: 'John Doe' },\n    collection: 'sensitive',\n    encrypt: true,\n    encryptionKey: anchora.generateEncryptionKey(32)\n  },\n  {\n    data: { productId: 'PROD-001', price: 99.99 },\n    collection: 'products',\n    hashOnly: true\n  }\n]);\n```\n\n**Options:**\n- `records` (Array, required) - Array of records to anchor (max 100)\n  - `data` (Object, required) - Data to anchor\n  - `collection` (String, optional) - Collection name\n  - `metadata` (Object, optional) - Additional metadata\n  - `encrypt` (Boolean, optional) - Enable encryption\n  - `encryptionKey` (String, required if encrypt=true) - Encryption key\n  - `hashOnly` (Boolean, optional) - Store only hash\n  - `webhookUrl` (String, optional) - Per-record webhook URL\n- `webhookUrl` (String, optional) - Global webhook URL for all records\n\n**Benefits:**\n- ⚡ Faster than individual anchoring\n- 💰 More cost-effective\n- 📊 Individual success/failure tracking\n- 🔄 Failed records don't block successful ones\n- 📦 Single API call for bulk operations\n\n### getHealth()\n\nGet system health status and monitor dependencies.\n\n```javascript\nconst health = await anchora.getHealth();\n\n// Returns:\n// {\n//   status: 'healthy',  // or 'degraded', 'unhealthy'\n//   service: 'Anchora API',\n//   version: '1.0.0',\n//   timestamp: '2025-12-25T10:00:00Z',\n//   checks: {\n//     mongodb: {\n//       status: 'connected',\n//       state: 'connected',\n//       database: 'anchoradb'\n//     },\n//     redis: {\n//       status: 'connected',\n//       state: 'ready'\n//     },\n//     worker: {\n//       status: 'healthy'\n//     }\n//   },\n//   responseTime: '45ms'\n// }\n```\n\n**Use cases:**\n- Health monitoring dashboards\n- Uptime checks\n- Dependency status tracking\n- Performance monitoring\n\n## File Operations\n\nUpload, hash, and verify files (documents, images, logs) directly through Anchora.\n\n### Supported File Formats\n\n- **Documents**: PDF, DOCX, TXT, JSON\n- **Images**: JPG, JPEG, PNG\n- **Logs**: LOG files\n- **Max Size**: 50MB per file\n\n### Hash File Locally\n\n```javascript\n// Hash a file without uploading\nconst result = await anchora.hashFile('./certificate.pdf');\n\nconsole.log('Hash:', result.hash);\nconsole.log('File:', result.fileInfo.name);\nconsole.log('Size:', result.fileInfo.sizeInMB, 'MB');\nconsole.log('Type:', result.fileInfo.mimeType);\n\n// Hash from Buffer\nconst fs = require('fs');\nconst buffer = fs.readFileSync('./certificate.pdf');\nconst bufferResult = await anchora.hashFile(buffer);\n```\n\n### Upload and Anchor File\n\n```javascript\n// Upload file to Anchora and anchor to blockchain\nconst result = await anchora.anchorFile('./certificate.pdf', {\n  metadata: {\n    studentId: 'STU12345',\n    degree: 'Bachelor of Science',\n    issueDate: '2025-05-15'\n  },\n  collection: 'university_certificates'\n});\n\nconsole.log('Record ID:', result.recordId);\nconsole.log('Hash:', result.hash);\nconsole.log('Status:', result.status); // QUEUED\nconsole.log('File Info:', result.fileInfo);\n```\n\n### Verify File\n\n```javascript\n// Verify file hasn't been tampered with\nconst verification = await anchora.verifyFile(\n  './certificate.pdf',\n  expectedHash\n);\n\nif (verification.hashMatches) {\n  console.log('✅ File is authentic');\n  \n  if (verification.blockchainVerification?.verified) {\n    console.log('✅ Verified on blockchain');\n  }\n} else {\n  console.log('❌ File has been tampered with');\n}\n```\n\n### Get File Upload Info\n\n```javascript\n// Get supported formats and limits\nconst info = await anchora.getFileUploadInfo();\n\nconsole.log('Supported:', info.supportedFormats);\nconsole.log('Max Size:', info.maxFileSizeInMB, 'MB');\n```\n\n### Real-World Use Case: University Certificates\n\n```javascript\n// Step 1: University uploads certificate\nconst cert = await anchora.anchorFile('./student-cert.pdf', {\n  metadata: {\n    studentId: 'STU12345',\n    studentName: 'John Doe',\n    degree: 'Bachelor of Science',\n    graduationDate: '2025-05-15',\n    issuer: 'University of Technology'\n  },\n  collection: 'certificates'\n});\n\n// Step 2: Student shares certificate + hash with employer\n// Step 3: Employer verifies certificate\nconst verify = await anchora.verifyFile('./student-cert.pdf', cert.hash);\n\nif (verify.hashMatches && verify.blockchainVerification?.verified) {\n  console.log('✅ Certificate is authentic and verified on blockchain');\n}\n```\n\n## Hash-Only Mode (Maximum Privacy)\n\nHash-only mode allows you to anchor data without storing it in Anchora - perfect for sensitive data and GDPR compliance.\n\n### When to Use Hash-Only Mode\n\n✅ **Use hash-only mode when:**\n- Handling sensitive/private data\n- GDPR/compliance requirements\n- You want full data ownership\n- Cost optimization needed\n- Building stateless architecture\n\n✅ **Use traditional mode when:**\n- Public data (certificates, documents)\n- Convenience over privacy\n- Anchora-managed verification\n\n### Hash-Only Example\n\n```javascript\n// 1. Anchor with hash-only mode\nconst result = await anchora.anchor(\n  {\n    patientId: 'P-12345',\n    diagnosis: 'Confidential',\n    treatment: 'Confidential'\n  },\n  {\n    collection: 'medical-records',\n    hashOnly: true  // ← Only hash stored in Anchora\n  }\n);\n\n// 2. YOU store the data in YOUR database\nawait db.collection('medical-records').insertOne({\n  patientId: 'P-12345',\n  diagnosis: 'Confidential',\n  treatment: 'Confidential',\n  vaas: {\n    hash: result.hash,\n    recordId: result.recordId\n  }\n});\n\n// 3. Later, verify with YOUR data\nconst record = await db.collection('medical-records').findOne({ patientId: 'P-12345' });\n\nconst verification = await anchora.verify(record, {\n  hash: record.vaas.hash\n});\n\nconsole.log('Data verified:', verification.verified);\n```\n\n### Benefits\n\n- 🔒 **Privacy**: Data never leaves your infrastructure\n- 👤 **Ownership**: You control all data\n- ⚖️ **Compliance**: GDPR-compliant by design\n- 💰 **Cost**: 60-93% storage reduction\n- 🏗️ **Architecture**: Stateless service (like OpenAI API)\n\n## Webhook Management\n\n### getWebhooks(options)\n\nGet webhook delivery history with filtering and pagination.\n\n```javascript\nconst webhooks = await anchora.getWebhooks({\n  status: 'FAILED',      // Filter by status: PENDING, SENT, FAILED\n  startDate: '2025-12-01T00:00:00Z',\n  endDate: '2025-12-25T23:59:59Z',\n  limit: 50,\n  offset: 0,\n  collection: 'orders'\n});\n\nconsole.log('Total webhooks:', webhooks.pagination.total);\nconsole.log('Summary:', webhooks.summary);\n// { PENDING: 10, SENT: 130, FAILED: 10 }\n\nwebhooks.data.forEach(webhook => {\n  console.log(`${webhook.hash} - ${webhook.webhookStatus}`);\n});\n```\n\n### retryWebhook(recordId)\n\nManually retry a failed webhook delivery (max 5 retries).\n\n```javascript\ntry {\n  const result = await anchora.retryWebhook('abc123');\n  \n  console.log('Webhook sent:', result.webhookStatus); // SENT\n  console.log('Retry count:', result.retryCount); // 2\n} catch (error) {\n  if (error.message.includes('Maximum retry attempts')) {\n    console.error('Max retries exceeded');\n  }\n}\n```\n\n## Batch Management\n\n### getBatches(options)\n\nList all batches with your project records.\n\n```javascript\nconst batches = await anchora.getBatches({\n  status: 'ANCHORED',    // Filter by status: PENDING, ANCHORED, FAILED\n  startDate: '2025-12-01T00:00:00Z',\n  limit: 20,\n  offset: 0,\n  sortBy: 'createdAt',\n  sortOrder: 'desc'      // asc or desc\n});\n\nconsole.log('Total batches:', batches.pagination.total);\nconsole.log('Summary:', batches.summary);\n// { PENDING: 2, ANCHORED: 20, FAILED: 3, totalRecords: 1250 }\n\nbatches.data.forEach(batch => {\n  console.log(`Batch ${batch.batchId}: ${batch.projectRecordCount} records`);\n  console.log('Sample records:', batch.sampleRecords.slice(0, 3));\n});\n```\n\n### getBatchDetails(batchId)\n\nGet detailed batch information with all your project records.\n\n```javascript\nconst details = await anchora.getBatchDetails(12345);\n\nconsole.log('Batch:', details.batch);\n// {\n//   batchId: 12345,\n//   merkleRoot: '0xabc...',\n//   recordCount: 50,\n//   blockNumber: 1234567,\n//   status: 'ANCHORED'\n// }\n\nconsole.log('Your records:', details.records.length);\nconsole.log('Stats:', details.stats);\n// {\n//   total: 10,\n//   byStatus: { ANCHORED: 10 },\n//   byCollection: { orders: 5, invoices: 5 },\n//   encrypted: 7,\n//   hashOnly: 2,\n//   withWebhooks: 8\n// }\n```\n\n## Analytics\n\n### getAnalytics(options)\n\nGet comprehensive usage analytics and metrics.\n\n```javascript\nconst analytics = await anchora.getAnalytics({\n  startDate: '2025-11-25T00:00:00Z',\n  endDate: '2025-12-25T23:59:59Z',\n  granularity: 'day'  // hour, day, week, month\n});\n\n// Overview\nconsole.log('Total records:', analytics.data.overview.totalRecords);\nconsole.log('Total batches:', analytics.data.overview.totalBatches);\nconsole.log('Success rate:', analytics.data.overview.successRate + '%');\n\n// Records by status\nconsole.log('Records:', analytics.data.records);\n// {\n//   total: 5000,\n//   byStatus: { queued: 50, batching: 25, anchored: 4900, failed: 25 }\n// }\n\n// Webhook statistics\nconsole.log('Webhooks:', analytics.data.webhooks);\n// {\n//   total: 3000,\n//   byStatus: { pending: 100, sent: 2800, failed: 100 },\n//   successRate: 93.3,\n//   avgRetries: 1\n// }\n\n// Encryption statistics\nconsole.log('Encryption rate:', analytics.data.encryption.encryptionRate + '%');\n\n// Time series data\nanalytics.data.timeSeries.forEach(point => {\n  console.log(`${point.date}: ${point.records} records, ${point.anchored} anchored`);\n});\n\n// Top collections\nanalytics.data.collections.forEach(col => {\n  console.log(`${col.name}: ${col.count} records (${col.encryptionRate}% encrypted)`);\n});\n\n// API usage\nconsole.log('API requests:', analytics.data.apiUsage.summary.totalRequests);\nconsole.log('Avg response time:', analytics.data.apiUsage.summary.avgResponseTime + 'ms');\n```\n\n### getAnalyticsSummary()\n\nGet quick analytics summary.\n\n```javascript\nconst summary = await anchora.getAnalyticsSummary();\n\nconsole.log('Total records:', summary.totalRecords);\nconsole.log('Total batches:', summary.totalBatches);\nconsole.log('Recent activity:', summary.recentActivity.slice(0, 5));\n```\n\n## Utility Methods\n\n### computeHash(data)\n\nCompute SHA-256 hash of data.\n\n```javascript\nconst hash = anchora.computeHash({ orderId: 'ORD-123' });\n// Returns: '3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b'\n```\n\n### verifyHash(data, expectedHash)\n\nVerify data matches expected hash.\n\n```javascript\nconst isValid = anchora.verifyHash(\n  { orderId: 'ORD-123' },\n  '3a7bd3e2...'\n);\n// Returns: true or false\n```\n\n## Encryption Methods\n\nAnchora SDK provides **industrial-grade encryption** using PBKDF2 + AES-256-GCM.\n\n📖 **[Complete Encryption Guide](./ENCRYPTION.md)** - See detailed documentation\n\n### Quick Start: Server-Side Encryption\n\n```javascript\n// Anchor with encryption (Anchora API encrypts server-side)\nconst result = await anchora.anchor(\n  { ssn: '123-45-6789', name: 'John Doe' },\n  {\n    encrypt: true,\n    encryptionKey: 'super-secure-key-32-chars-minimum-here'\n  }\n);\n\nconsole.log('Encrypted:', result.encrypted); // true\nconsole.log('Algorithm:', result.encryptionAlgorithm); // AES-256-GCM-PBKDF2\n```\n\n### encrypt(data, encryptionKey)\n\nEncrypt data locally with PBKDF2 + AES-256-GCM.\n\n```javascript\nconst encrypted = await anchora.encrypt(\n  { ssn: '123-45-6789' },\n  'super-secure-key-32-chars-minimum-here'\n);\n\n// Returns:\n// {\n//   encrypted: 'a3f2b1c4...',\n//   iv: 'f28d7b7e...',\n//   authTag: 'c3622a33...',\n//   salt: '990fd768...',\n//   iterations: 100000,\n//   algorithm: 'AES-256-GCM-PBKDF2'\n// }\n```\n\n### decrypt(encryptedData, encryptionKey, iv, authTag, salt, iterations)\n\nDecrypt PBKDF2 encrypted data.\n\n```javascript\nconst decrypted = await anchora.decrypt(\n  encrypted.encrypted,\n  'super-secure-key-32-chars-minimum-here',\n  encrypted.iv,\n  encrypted.authTag,\n  encrypted.salt,\n  encrypted.iterations\n);\n```\n\n### generateEncryptionKey(length)\n\nGenerate a cryptographically secure random key.\n\n```javascript\nconst key = anchora.generateEncryptionKey(32);\n// Returns: 'aB3$xY9@kL2#...' (32 characters)\n```\n\n### validateEncryptionKey(encryptionKey)\n\nValidate encryption key meets security requirements (32 char minimum).\n\n```javascript\ntry {\n  anchora.validateEncryptionKey('short'); // Throws error\n} catch (error) {\n  console.error(error.message);\n  // 'Encryption key must be at least 32 characters for security'\n}\n```\n\n## Advanced Methods\n\n### anchorWithEncryption(data, encryptionKey, options)\n\nAnchor data with server-side encryption (convenience method).\n\n```javascript\nconst result = await anchora.anchorWithEncryption(\n  { sensitiveData: 'secret' },\n  'super-secure-key-32-chars-minimum-here',\n  { metadata: { type: 'sensitive' } }\n);\n\n// Equivalent to:\n// await anchora.anchor(data, { encrypt: true, encryptionKey: key })\n\n// Returns:\n// {\n//   success: true,\n//   hash: '...',\n//   encrypted: true,\n//   encryptionAlgorithm: 'AES-256-GCM-PBKDF2',\n//   ...\n// }\n```\n\n### verifyWithDecryption(encryptedData, encryptionKey, iv, authTag, salt, iterations, expectedHash)\n\nVerify and decrypt data, checking for tampering.\n\n```javascript\nconst result = await anchora.verifyWithDecryption(\n  encrypted.encrypted,\n  'super-secure-key-32-chars-minimum-here',\n  encrypted.iv,\n  encrypted.authTag,\n  encrypted.salt,\n  encrypted.iterations,\n  expectedHash\n);\n\n// Returns:\n// {\n//   verified: true,\n//   decryptedData: { ... },\n//   tampered: false,\n//   ...\n// }\n```\n\n## Real-World Examples\n\n### E-commerce Order Verification\n\n```javascript\n// When order is created\nconst order = {\n  orderId: 'ORD-12345',\n  userId: 'user-123',\n  total: 999.99,\n  items: [...]\n};\n\n// Save to your database\nawait db.orders.insertOne(order);\n\n// Anchor to Anchora\nconst result = await anchora.anchor(order);\n\n// Store proof in your database\nawait db.orders.updateOne(\n  { orderId: 'ORD-12345' },\n  { \n    $set: { \n      anchora_hash: result.hash,\n      anchora_timestamp: result.timestamp\n    }\n  }\n);\n\n// Later: Verify order hasn't been tampered with\nconst order = await db.orders.findOne({ orderId: 'ORD-12345' });\nconst verification = await anchora.verify(order);\n\nif (!verification.verified) {\n  console.error('Order has been tampered with!');\n}\n```\n\n### Healthcare Records with Encryption\n\n```javascript\n// Store encrypted medical record\nconst patientData = {\n  patientId: 'P-123',\n  diagnosis: 'Type 2 Diabetes',\n  medication: 'Metformin 500mg'\n};\n\nconst encryptionKey = anchora.generateEncryptionKey();\n\n// Encrypt and anchor\nconst result = await anchora.anchorWithEncryption(\n  patientData,\n  encryptionKey,\n  { metadata: { type: 'medical_record' } }\n);\n\n// Store in database\nawait db.patients.insertOne({\n  patientId: 'P-123',\n  encryptedData: result.encryptedData,\n  anchora_hash: result.hash,\n  encryptionKey: encryptionKey // Store securely!\n});\n\n// Later: Retrieve and verify\nconst record = await db.patients.findOne({ patientId: 'P-123' });\n\nconst verification = await anchora.verifyWithDecryption(\n  record.encryptedData,\n  record.encryptionKey,\n  record.anchora_hash\n);\n\nif (verification.tampered) {\n  console.error('Medical record has been tampered with!');\n} else {\n  console.log('Patient data:', verification.decryptedData);\n}\n```\n\n### Financial Transaction Audit Trail\n\n```javascript\n// Daily batch anchoring\nconst todayTransactions = await db.transactions.find({\n  date: { $gte: startOfDay, $lt: endOfDay }\n});\n\nconst result = await anchora.anchor({\n  date: new Date().toISOString(),\n  count: todayTransactions.length,\n  totalAmount: todayTransactions.reduce((sum, t) => sum + t.amount, 0),\n  transactions: todayTransactions.map(t => t.transactionId)\n});\n\n// Store batch proof\nawait db.auditLog.insertOne({\n  date: new Date(),\n  type: 'daily_batch',\n  anchora_hash: result.hash,\n  anchora_proof: result.recordId\n});\n```\n\n## Error Handling\n\n```javascript\nconst { AnchoraClient, ValidationError, AuthenticationError } = require('@anchora/sdk');\n\ntry {\n  const result = await anchora.anchor(data);\n} catch (error) {\n  if (error instanceof ValidationError) {\n    console.error('Invalid data:', error.message);\n  } else if (error instanceof AuthenticationError) {\n    console.error('Authentication failed:', error.message);\n  } else {\n    console.error('Unexpected error:', error);\n  }\n}\n```\n\n## Error Types\n\n- `ValidationError` - Invalid input data\n- `AuthenticationError` - API key invalid or expired\n- `NetworkError` - Network connectivity issues\n- `VerificationError` - Data verification failed\n- `AnchoraError` - General Anchora error\n\n## Best Practices\n\n1. **Store Hashes, Not Data** - Only store the hash and proof in your database\n2. **Use Encryption** - Encrypt sensitive data before storing\n3. **Verify on Read** - Always verify data integrity when reading critical records\n4. **Batch Operations** - Anchor multiple records together for efficiency\n5. **Handle Errors** - Implement proper error handling for all operations\n6. **Secure Keys** - Store encryption keys and API keys securely\n\n## Support & Links\n\n- **Website:** https://www.anchora.co.in\n- **GitHub (this repo):** https://github.com/anchora-labs/anchora-sdk-js\n- **npm:** https://www.npmjs.com/package/@anchora/sdk\n- **Issues / bug reports:** https://github.com/anchora-labs/anchora-sdk-js/issues\n- **Email:** vigneshwaran.bs@anchora.co.in\n\n## Contributing\n\nPRs welcome — please open an issue first to discuss the change. Bug reports and security disclosures appreciated; for security issues, please email rather than filing a public issue.\n\n## License\n\nMIT — see [LICENSE](./LICENSE) for details.\n","readmeFilename":"README.md"}