Arkipel JavaScript API Client

A comprehensive JavaScript client library for interacting with Arkipel communities. This library provides a clean, modern interface for the Arkipel API with support for both keypair and token authentication.

Features

  • πŸ” Dual Authentication: Support for both Ed25519 keypair and API token authentication
  • ⚑ Asynchronous Operations: Built-in handling for Arkipel’s async message processing
  • πŸ›‘οΈ Error Handling: Comprehensive error classes and retry logic
  • πŸ”„ Connection Management: HTTP client with proper timeouts and SSL verification
  • πŸ“ Type-Safe: Modern JavaScript with clear interfaces
  • πŸ§ͺ Well-Tested: Examples and testing utilities included

Quick Start

Installation

cd docs/examples/javascript
npm install

Basic Usage

Token Authentication (Easiest)

import { ArkipelClient } from "./src/index.js";

const client = ArkipelClient.withToken(
  "https://your-arkipel-site.com",
  "your_community_public_key",
  "your_api_token_here",
);

// Test connection
const ping = await client.ping();
console.log("Connection test:", ping.isSuccess());

// Get person categories
const categories = await client.listPersonCategories();
console.log("Categories:", categories.getData());

Keypair Authentication (More Secure)

import { ArkipelClient } from "./src/index.js";

const client = ArkipelClient.withKeypair(
  "https://your-arkipel-site.com",
  "your_community_public_key",
  "your_64_character_hex_private_key",
  "your_zbase32_public_key",
);

// Works the same way as token auth!
const ping = await client.ping();
console.log("Connection test:", ping.isSuccess());
# Required
export ARKIPEL_COMMUNITY_PUBLIC_KEY="your_community_key"

# Choose ONE authentication method:

# Option 1: API Token
export ARKIPEL_API_TOKEN="your_api_token"

# Option 2: Keypair
export ARKIPEL_PRIVATE_KEY_HEX="your_64_character_hex_private_key"
export ARKIPEL_PUBLIC_KEY_ZBASE32="your_zbase32_public_key"

# Optional
export ARKIPEL_SITE_URL="https://your-site.com"  # defaults to localhost
import { ArkipelClient } from "./src/index.js";

// Auto-detects authentication from environment
const client = ArkipelClient.fromEnvironment();

// Test the connection
const ping = await client.ping();
console.log("Connected to Arkipel!");

API Methods

System Operations

// Test connection
const ping = await client.ping();

// Query message status (for async operations)
const status = await client.queryMessage("message_id_here");

People Management

// Get a single person
const person = await client.getPerson(123);
const personByImport = await client.getPersonByImportId("my_import_id");

// List people with filters
const people = await client.listPeople({
  per_page: 10,
  page: 1,
  first_name_cont: "John",
});

// Create/update person (async operation)
const createResponse = await client.createPerson({
  first_name: "John",
  last_name: "Doe",
  email: "john@example.com",
  import_id: "my_unique_id",
});

// Create and wait for completion
const result = await client.createPersonAndWait({
  first_name: "Jane",
  last_name: "Smith",
});

if (result.isSuccess()) {
  console.log("Person created:", result.data);
} else {
  console.log("Creation failed:", result.error);
}

// Get person categories
const categories = await client.listPersonCategories();

Other Resources (When Available)

// Distributions (when implemented)
const distributions = await client.listDistributions();
const dist = await client.createDistribution({...});

// Procurements (when implemented)
const procurements = await client.listProcurements();
const procurement = await client.createProcurement({...});

// Forms (when implemented)
const forms = await client.listForms();
const filledForm = await client.fillForm(formId, {...});

Async Operations

Arkipel processes many operations asynchronously. The client handles this automatically:

// All mutations return immediately with a message_id
const response = await client.createPerson({...});

if (response.isAsynchronous()) {
  console.log('Operation started, ID:', response.messageId);

  // Wait for completion
  const result = await client.waitForMessage(response.messageId);

  if (result.isSuccess()) {
    console.log('Success:', result.data);
  } else {
    console.log('Failed:', result.error);
  }
}

// Or use the convenience method
const result = await client.createPersonAndWait({...});

Advanced Async Handling

import { AsyncOperationManager } from './src/async/index.js';

const manager = client.getAsyncManager();

// Wait for multiple operations
const operations = [
  await client.createPerson({...}),
  await client.createPerson({...}),
  await client.createPerson({...})
];

const results = await manager.waitForMultiple(
  operations.map(op => op.messageId)
);

// Get operation status
const status = manager.getStatus();
console.log('Operations:', status);

Error Handling

The client provides detailed error information:

try {
  const response = await client.createPerson({...});
} catch (error) {
  if (error.name === 'ArkipelValidationError') {
    console.log('Validation failed:', error.message);
    console.log('Details:', error.details);
  } else if (error.name === 'ArkipelAuthenticationError') {
    console.log('Check your credentials');
  } else if (error.name === 'ArkipelNetworkError') {
    console.log('Network issue - check connection');
  }

  // All errors include helpful information
  console.log('Error code:', error.code);
  console.log('Error details:', error.details);
}

Configuration Options

const client = ArkipelClient.withToken(siteUrl, communityKey, token, {
  timeout: 10000, // Request timeout (ms)
  openTimeout: 5000, // Connection timeout (ms)
  readTimeout: 10000, // Read timeout (ms)
  maxRetries: 3, // Max retry attempts
});

Examples

Quick Test

Run the quick test with environment variables:

# Set your credentials
export ARKIPEL_SITE_URL="https://your-site.com"
export ARKIPEL_COMMUNITY_PUBLIC_KEY="your_key"
export ARKIPEL_API_TOKEN="your_token"

# Run the test
npm run example:quick

# Or directly:
node examples/quick-test.js

Token Authentication Example

# Edit the example file with your credentials
# Then run:
npm run example:token

Keypair Authentication Example

# Edit the example file with your keypair
# Then run:
npm run example:keypair

Generate New Keypair

import { MessageSigner } from "./src/crypto/MessageSigner.js";

const keypair = MessageSigner.generateKeypair();
console.log("Private Key (Hex):", keypair.privateKeyHex);
console.log("Public Key (Hex):", keypair.publicKeyHex);
console.log("Public Key (ZBase32):", keypair.publicKeyZbase32);

Testing with Real API

Step 1: Get Your Credentials

  1. For Token Authentication:
    • Log in to your Arkipel community
    • Go to Network β†’ Authorizations
    • Generate an API token
  2. For Keypair Authentication:
    • Generate a keypair (see example above)
    • Add your public key to the community’s authorization list

Step 2: Set Environment Variables

# Replace with your actual values
export ARKIPEL_SITE_URL="https://your-community.arkipel.com"
export ARKIPEL_COMMUNITY_PUBLIC_KEY="your_community_public_key"
export ARKIPEL_API_TOKEN="your_actual_api_token"

Step 3: Run the Test

cd docs/examples/javascript
npm install
node examples/quick-test.js

The test will:

  • βœ… Test connection with ping
  • βœ… Query person categories
  • βœ… Create a person (async)
  • βœ… Wait for operation completion
  • βœ… List people

Architecture

The client is built with these core components:

  • ArkipelConfig: Configuration management and validation
  • HttpClient: HTTP client with proper settings and retries
  • AuthHandler: Authentication (keypair vs token)
  • MessageSigner: Ed25519 cryptography and ZBase32 encoding
  • ArkipelResponse: Response parsing and handling
  • AsyncOperation: Async operation management and polling
  • Error Classes: Comprehensive error hierarchy

Security Best Practices

  1. Use Keypair Authentication for production environments
  2. Never commit private keys to version control
  3. Use environment variables for credentials
  4. Enable SSL verification in production (default)
  5. Validate all inputs before sending to API

Development

Running Tests

# Install dependencies
npm install

# Run quick test (requires environment setup)
node examples/quick-test.js

# Run examples
npm run example:token
npm run example:keypair

Project Structure

src/
β”œβ”€β”€ config/          # Configuration management
β”œβ”€β”€ auth/            # Authentication handlers
β”œβ”€β”€ http/            # HTTP client
β”œβ”€β”€ crypto/          # Ed25519 cryptography
β”œβ”€β”€ responses/       # Response parsing
β”œβ”€β”€ async/           # Async operation management
β”œβ”€β”€ errors/          # Error classes
└── client/          # Main client class
examples/            # Usage examples

API Status

This client supports these Arkipel API operations:

βœ… Implemented

  • ping - Health check
  • arkipel_messages:query - Message status
  • person:query - Get single person
  • person_categories:query - List categories
  • people:upsert - Create/update people (async)

🚧 In Progress

  • people:query - List people with filters

πŸ“… Planned

  • distributions:* - Distribution management
  • procurements:* - Procurement management
  • forms:* - Form operations

Support

  • Documentation: AGENTS.md
  • API Specs: specs/
  • Issues: Report to Arkipel team
  • Examples: See examples/ directory

License

MIT License - See LICENSE.md for details.