Skip to content

TypeScript SDK

The official Islamic Open Finance™ TypeScript SDK provides full type safety and IntelliSense support.

Installation

bash
npm install @iof/sdk
# or
pnpm add @iof/sdk
# or
yarn add @iof/sdk

Requirements

  • Node.js 18 or later
  • TypeScript 5.0 or later (for type definitions)

Quick Start

typescript
import { IOFClient } from "@iof/sdk";

const client = new IOFClient({
  apiKey: process.env.IOF_API_KEY!,
  environment: "sandbox", // or 'production'
});

// Create a contract
const contract = await client.contracts.create({
  type: "murabaha",
  jurisdiction: "SA",
  parties: {
    financier: { entityId: "ent_123" },
    customer: { entityId: "ent_456" },
  },
  asset: {
    description: "Vehicle financing",
    costPrice: { amount: 100000, currency: "SAR" },
    profitMargin: 0.08,
  },
  terms: {
    paymentSchedule: "monthly",
    numberOfInstallments: 48,
  },
});

Configuration

typescript
import { IOFClient } from "@iof/sdk";

const client = new IOFClient({
  // Required
  apiKey: "sk_live_...",

  // Optional
  environment: "production", // 'sandbox' | 'production'
  timeout: 30000, // Request timeout in ms
  maxRetries: 3, // Retry failed requests
  baseUrl: "https://api.islamicopenfinance.com", // Custom base URL
});

Available Resources

Contracts

typescript
// Create
const contract = await client.contracts.create({ ... });

// Get
const contract = await client.contracts.get("con_123");

// List
const contracts = await client.contracts.list({
  status: "active",
  type: "murabaha",
  page: 1,
  perPage: 20,
});

// Update (draft only)
const updated = await client.contracts.update("con_123", { ... });

// Submit for review
await client.contracts.submit("con_123");

// Activate
await client.contracts.activate("con_123");

// Terminate
await client.contracts.terminate("con_123", {
  reason: "early_settlement",
});

Entities

typescript
// Create individual
const individual = await client.entities.create({
  type: "individual",
  name: "Ahmed Al-Rashid",
  jurisdiction: "SA",
  nationalId: "1234567890",
});

// Create institution
const institution = await client.entities.create({
  type: "institution",
  name: "Al Rajhi Bank",
  jurisdiction: "SA",
  registrationNumber: "123456",
});

// KYC verification
const kyc = await client.kyc.verify("ent_123", {
  documentType: "national_id",
  documentNumber: "1234567890",
});

Webhooks

typescript
// Create subscription
const webhook = await client.webhooks.create({
  url: "https://example.com/webhooks",
  events: ["contract.created", "payment.received"],
  secret: "whsec_...",
});

// List subscriptions
const webhooks = await client.webhooks.list();

// Update subscription
await client.webhooks.update("wh_123", {
  events: ["contract.created"],
});

// Delete subscription
await client.webhooks.delete("wh_123");

Pagination

The SDK provides automatic pagination support:

typescript
// Iterate through all pages automatically
for await (const contract of client.contracts.list()) {
  console.log(contract.id);
}

// Or get a single page
const page = await client.contracts.list({ page: 1, perPage: 50 });
console.log(page.data); // Array of contracts
console.log(page.pagination); // { page, perPage, total, totalPages }

Error Handling

typescript
import {
  IOFError,
  ValidationError,
  AuthenticationError,
  RateLimitError,
  NotFoundError,
} from "@iof/sdk";

try {
  await client.contracts.create({ ... });
} catch (error) {
  if (error instanceof ValidationError) {
    console.log("Validation errors:", error.details);
    for (const detail of error.details) {
      console.log(`${detail.field}: ${detail.message}`);
    }
  } else if (error instanceof AuthenticationError) {
    console.log("Invalid API key");
  } else if (error instanceof RateLimitError) {
    console.log("Rate limited, retry after:", error.retryAfter, "seconds");
  } else if (error instanceof NotFoundError) {
    console.log("Resource not found");
  } else if (error instanceof IOFError) {
    console.log("API error:", error.code, error.message);
  }
}

Webhook Signature Verification

typescript
import { verifyWebhookSignature } from "@iof/sdk/webhooks";
import { Request, Response } from "express";

app.post("/webhooks", (req: Request, res: Response) => {
  const signature = req.headers["x-iof-signature"] as string;
  const payload = req.body;

  const isValid = verifyWebhookSignature(
    payload,
    signature,
    process.env.WEBHOOK_SECRET!,
  );

  if (!isValid) {
    return res.status(401).send("Invalid signature");
  }

  // Process webhook
  const event = payload;
  switch (event.type) {
    case "contract.created":
      console.log("Contract created:", event.data.id);
      break;
    case "payment.received":
      console.log("Payment received:", event.data.amount);
      break;
  }

  res.status(200).send("OK");
});

TypeScript Types

All types are exported for use in your application:

typescript
import type {
  Contract,
  ContractType,
  ContractStatus,
  Entity,
  EntityType,
  Webhook,
  WebhookEvent,
  Money,
  Pagination,
} from "@iof/sdk";

function processContract(contract: Contract) {
  if (contract.status === "active") {
    // Type-safe access
    console.log(contract.payment.monthlyAmount);
  }
}

Advanced Configuration

Custom HTTP Client

typescript
import { IOFClient } from "@iof/sdk";

const client = new IOFClient({
  apiKey: "sk_...",
  httpClient: {
    fetch: customFetch,
    headers: {
      "X-Custom-Header": "value",
    },
  },
});

Request Interceptors

typescript
client.on("request", (request) => {
  console.log("Request:", request.method, request.url);
});

client.on("response", (response) => {
  console.log("Response:", response.status);
});

Next Steps

Licensed under the Apache License 2.0