746 lines
20 KiB
Markdown
746 lines
20 KiB
Markdown
# JLINC SDK
|
|
|
|
[](https://www.npmjs.com/package/@jlinc/sdk)
|
|
[](./LICENSE)
|
|
|
|
A TypeScript/JavaScript SDK for the [JLINC](https://www.jlinc.io) API enabling verifiable data-sharing agreements, cryptographically signed data exchange, and zero-knowledge auditing.
|
|
|
|
## Overview
|
|
|
|
The JLINC SDK provides a unified interface to the JLINC Server API, covering:
|
|
|
|
- **Identity management** - Create and resolve decentralized identifiers (DIDs) with federation-formatted short names.
|
|
- **Verifiable Contractual Agreements (VCAs)** - Produce and cross-sign agreements that govern data-sharing permissions.
|
|
- **Cryptographic event records** - Produce, retrieve, and process data exchange events under agreement governance.
|
|
- **Zero-knowledge auditing** - Retrieve and verify tamper-proof audit records from third-party archives.
|
|
- **Fine-grained access control** - Check AuthZEN-formatted permissions before executing sensitive operations.
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
npm install @jlinc/sdk
|
|
```
|
|
|
|
```bash
|
|
yarn add @jlinc/sdk
|
|
```
|
|
|
|
```bash
|
|
pnpm add @jlinc/sdk
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
```typescript
|
|
import { init, createEntity, produceAgreement, processAgreement, produceEvent, getAudits, verifyAudit, auth } from "@jlinc/sdk";
|
|
|
|
// 1. Initialize the SDK with your JLINC Server configuration
|
|
init({
|
|
apiKey: process.env.JLINC_API_KEY!,
|
|
apiUrl: process.env.JLINC_API_URL!,
|
|
archiveUrl: process.env.JLINC_ARCHIVE_URL!,
|
|
archiveKey: process.env.JLINC_ARCHIVE_KEY!,
|
|
fedidUrl: process.env.JLINC_FEDID_URL!,
|
|
}, {
|
|
// Optional: set a default agreement ID fallback
|
|
agreementId: "00000000-0000-0000-0000-000000000000",
|
|
});
|
|
|
|
// 2. Create an identity
|
|
const entity = await createEntity({
|
|
shortName: `my-app@${(await getDomains({ auth: { subject: { type: "user", id: "admin" }, action: { name: "read" }, resource: { type: "data", id: "demo" } } }))[0]}`,
|
|
});
|
|
|
|
// 3. Produce and process an agreement
|
|
const agreement = await produceAgreement({
|
|
data: {
|
|
references: ["https://sisa.jlinc.org/v1/34020c5fb59ebc6507ebca4eb38090aec1097c6aec8d2ae2250ddfed4b4aa63c"],
|
|
permitted: ["data-sharing"],
|
|
prohibited: ["non-delegable"],
|
|
shortNames: [entity.didDoc.shortName],
|
|
validRoles: ["provider", "user", "third-party"],
|
|
},
|
|
shortName: entity.didDoc.shortName,
|
|
role: "provider",
|
|
});
|
|
|
|
await processAgreement({
|
|
agreementId: agreement.created.agreementId,
|
|
shortName: entity.didDoc.shortName,
|
|
role: "user",
|
|
});
|
|
|
|
// 4. Exchange data under the agreement
|
|
const event = await produceEvent({
|
|
type: "data",
|
|
senderShortName: "sender@domain.tld",
|
|
recipientShortName: "recipient@domain.tld",
|
|
agreementId: agreement.created.agreementId,
|
|
meta: { myCustomId: "unique-id-123" },
|
|
data: { query: "Hello, world!" },
|
|
});
|
|
|
|
// 5. Audit and verify
|
|
const audits = await getAudits({ agreementId: agreement.created.agreementId });
|
|
const result = await verifyAudit({
|
|
audits: audits.auditRecords || [],
|
|
shortNames: ["sender@domain.tld", "recipient@domain.tld"],
|
|
});
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### `init(config, defaults?)`
|
|
|
|
Initialize the SDK with your server credentials and optional default parameters. All subsequent API calls inherit these settings.
|
|
|
|
```typescript
|
|
init(
|
|
{
|
|
apiKey: string; // Bearer token for the Core API
|
|
apiUrl: string; // JLINC Core API base URL (e.g. "https://api.jlinc.io")
|
|
archiveUrl: string; // JLINC Archiver base URL for audit records
|
|
archiveKey: string; // Bearer token for the Archiver API
|
|
fedidUrl: string; // FedID service URL for identity resolution
|
|
},
|
|
defaults?: {
|
|
agreementId?: string; // Default agreement ID (fallback for all calls that accept one)
|
|
}
|
|
): void
|
|
```
|
|
|
|
| Parameter | Description |
|
|
|-----------|-------------|
|
|
| `apiKey` | Bearer token for authenticating requests to the Core API |
|
|
| `apiUrl` | Base URL of the JLINC Core API endpoint |
|
|
| `archiveUrl` | Base URL of the JLINC Archiver (audit) endpoint |
|
|
| `archiveKey` | Bearer token for authenticating requests to the Archiver API |
|
|
| `fedidUrl` | URL of the FedID service for domain resolution and identity operations |
|
|
|
|
## API Reference
|
|
|
|
All methods return the parsed response data from the JLINC API. Where responses include a `created` object, it contains the newly generated identifiers (e.g., `created.agreementId`, `created.eventId`).
|
|
|
|
---
|
|
|
|
### `auth(params)`
|
|
|
|
Perform a fine-grained authorization check using an AuthZEN-formatted request. Returns `{ decision: true }` if the subject is permitted, or `{ decision: false }` if denied.
|
|
|
|
```typescript
|
|
type AuthSubject = {
|
|
type: string; // e.g. "user", "system", "ai-agent"
|
|
id: string; // Unique identifier for the subject
|
|
};
|
|
|
|
type AuthAction = {
|
|
name: string; // e.g. "read", "write", "delete"
|
|
};
|
|
|
|
type AuthResource = {
|
|
type: string; // e.g. "data", "agreement", "event"
|
|
id: string; // Resource identifier
|
|
properties?: {
|
|
ownerID?: string; // Optional data owner ID
|
|
};
|
|
};
|
|
|
|
type AuthParams = {
|
|
subject: AuthSubject;
|
|
action: AuthAction;
|
|
resource: AuthResource;
|
|
};
|
|
|
|
auth(params: AuthParams): Promise<{ decision: boolean }>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const result = await auth({
|
|
subject: { type: "user", id: "myuser" },
|
|
action: { name: "read" },
|
|
resource: {
|
|
type: "data",
|
|
id: "1234",
|
|
properties: { ownerID: "owner@test.com" },
|
|
},
|
|
});
|
|
|
|
if (result.decision) {
|
|
// Proceed with the operation
|
|
} else {
|
|
// Deny access
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### `getDomains(params)`
|
|
|
|
Retrieve the list of available federation domains configured on your JLINC Server.
|
|
|
|
```typescript
|
|
type GetDomainsParams = {
|
|
fedidUrl?: string; // Optional: override the configured fedidUrl
|
|
auth: AuthParams; // AuthZEN-formatted authorization payload
|
|
};
|
|
|
|
getDomains(params: GetDomainsParams): Promise<string[]>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const domains = await getDomains({
|
|
auth: {
|
|
subject: { type: "user", id: "admin" },
|
|
action: { name: "read" },
|
|
resource: { type: "data", id: "domains" },
|
|
},
|
|
});
|
|
|
|
console.log(domains); // ["test.jlinc.io", "example.com", ...]
|
|
```
|
|
|
|
---
|
|
|
|
### `createEntity(params)`
|
|
|
|
Create a new identity (entity) with a federation-formatted short name. Returns the entity's DID document.
|
|
|
|
```typescript
|
|
type CreateEntityParams = {
|
|
fedidUrl?: string; // Optional: override the configured fedidUrl
|
|
shortName: string; // Federation-format name: "name@domain.tld"
|
|
};
|
|
|
|
createEntity(params: CreateEntityParams): Promise<{ didDoc: { shortName: string; did: string; ... } }>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const domain = (await getDomains({ auth: /* ... */ }))[0];
|
|
|
|
const system = await createEntity({
|
|
fedidUrl: "http://localhost:8881",
|
|
shortName: `system@${domain}`,
|
|
});
|
|
|
|
console.log(system.didDoc.shortName); // "system@test.jlinc.io"
|
|
console.log(system.didDoc.did); // "did:jlinc:..."
|
|
```
|
|
|
|
---
|
|
|
|
### `getEntity(params)`
|
|
|
|
Retrieve an existing entity's DID document by its short name.
|
|
|
|
```typescript
|
|
type GetEntityParams = {
|
|
shortName: string; // The entity's federation-format short name
|
|
};
|
|
|
|
getEntity(params: GetEntityParams): Promise<{ data: { didDoc: { shortName: string; did: string; ... } } }>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const result = await getEntity({ shortName: "system@test.jlinc.io" });
|
|
console.log(result.data.didDoc.shortName);
|
|
```
|
|
|
|
---
|
|
|
|
### `produceAgreement(params)`
|
|
|
|
Create a Verifiable Contractual Agreement (VCA). The agreement is cryptographically signed, audited, and delivered to the archive service.
|
|
|
|
```typescript
|
|
type ProduceAgreementParams = {
|
|
data: {
|
|
references?: string[]; // External references (e.g. SISA policy URIs)
|
|
permitted?: string[]; // Allowed operations
|
|
prohibited?: string[]; // Disallowed operations
|
|
shortNames?: string[]; // Entities that must sign before the agreement is valid
|
|
validRoles?: string[]; // Permitted roles (e.g. "provider", "user", "third-party")
|
|
public?: boolean; // If true, the agreement is publicly resolvable by any API key
|
|
};
|
|
shortName: string; // Entity that produces (initially signs) the agreement
|
|
role: string; // Role for the initial signature
|
|
archive?: {
|
|
url: string; // Optional: override the configured archiveUrl
|
|
key: string; // Optional: override the configured archiveKey
|
|
};
|
|
};
|
|
|
|
produceAgreement(params: ProduceAgreementParams): Promise<{ created: { agreementId: string }, ... }>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const agreement = await produceAgreement({
|
|
data: {
|
|
references: ["https://sisa.jlinc.org/v1/34020c5fb59ebc6507ebca4eb38090aec1097c6aec8d2ae2250ddfed4b4aa63c"],
|
|
permitted: ["data-sharing"],
|
|
prohibited: ["non-delegable"],
|
|
shortNames: [provider.didDoc.shortName],
|
|
validRoles: ["provider", "user", "third-party"],
|
|
},
|
|
shortName: provider.didDoc.shortName,
|
|
role: "provider",
|
|
});
|
|
|
|
console.log(agreement.created.agreementId); // "58810f16-b976-41f0-..."
|
|
```
|
|
|
|
---
|
|
|
|
### `processAgreement(params)`
|
|
|
|
Cross-sign an agreement as a second entity, finalizing its validity. This is how the "user" party agrees to the terms set by the "provider".
|
|
|
|
```typescript
|
|
type ProcessAgreementParams = {
|
|
agreementId?: string; // Optional: falls back to init() defaults.agreementId
|
|
shortName: string; // Entity that processes (cross-signs) the agreement
|
|
role: string; // Role for this entity's signature
|
|
archive?: {
|
|
url: string;
|
|
key: string;
|
|
};
|
|
};
|
|
|
|
processAgreement(params: ProcessAgreementParams): Promise<...>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
await processAgreement({
|
|
agreementId: agreement.created.agreementId,
|
|
shortName: user.didDoc.shortName,
|
|
role: "user",
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### `getAgreement(params)`
|
|
|
|
Retrieve an agreement, optionally including its signatures. Falls back to the default `agreementId` from `init()` if not specified.
|
|
|
|
```typescript
|
|
type GetAgreementParams = {
|
|
agreementId?: string; // Optional: falls back to init() defaults.agreementId
|
|
includeSignatures?: boolean; // Whether to include signature data
|
|
};
|
|
|
|
getAgreement(params: GetAgreementParams): Promise<...>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const agreement = await getAgreement({
|
|
agreementId: "58810f16-b976-41f0-9566-2c26f174b592",
|
|
includeSignatures: true,
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### `produceEvent(params)`
|
|
|
|
Produce a cryptographically signed event record - used when two entities exchange data (e.g., user input, agent handoff, API call).
|
|
|
|
```typescript
|
|
type ProduceEventParams = {
|
|
type: string; // Event type (e.g. "data", "command", "result")
|
|
senderShortName: string; // Sending entity's short name
|
|
recipientShortName: string; // Receiving entity's short name
|
|
agreementId?: string; // Optional: falls back to init() defaults.agreementId (use "nil" ID for audits only)
|
|
meta?: Record<string, unknown>; // Custom metadata for indexing and lookups
|
|
data: unknown; // The actual payload being exchanged
|
|
archive?: {
|
|
url: string;
|
|
key: string;
|
|
};
|
|
};
|
|
|
|
produceEvent(params: ProduceEventParams): Promise<{ created: { eventId: string }, ... }>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const event = await produceEvent({
|
|
type: "data",
|
|
senderShortName: "alice@test.jlinc.io",
|
|
recipientShortName: "bob@test.jlinc.io",
|
|
agreementId: agreement.created.agreementId,
|
|
meta: { myCustomId: "unique-identifier-456" },
|
|
data: { query: "Why am I making this?" },
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### `getEvent(params)`
|
|
|
|
Retrieve an event by its unique ID or by custom metadata keys.
|
|
|
|
```typescript
|
|
type GetEventParams = {
|
|
eventId?: string; // Optional: lookup by event ID
|
|
meta?: Record<string, unknown>; // Optional: lookup by meta keys (AND logic for multiple keys)
|
|
};
|
|
|
|
getEvent(params: GetEventParams): Promise<...>;
|
|
```
|
|
|
|
**Example - by ID:**
|
|
|
|
```typescript
|
|
const event = await getEvent({ eventId: "evt-12345" });
|
|
```
|
|
|
|
**Example - by meta ID:**
|
|
|
|
```typescript
|
|
const event = await getEvent({
|
|
meta: { myCustomId: "unique-identifier-456" },
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### `processEvent(params)`
|
|
|
|
Cross-sign an event to indicate the recipient has received and will use the data. This finalizes the event record.
|
|
|
|
```typescript
|
|
type ProcessEventParams = {
|
|
eventId: string; // The event to process
|
|
shortName: string; // Receiving entity that processes the event
|
|
archive?: {
|
|
url: string;
|
|
key: string;
|
|
};
|
|
};
|
|
|
|
processEvent(params: ProcessEventParams): Promise<...>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
await processEvent({
|
|
eventId: event.created.eventId,
|
|
shortName: "bob@test.jlinc.io",
|
|
});
|
|
```
|
|
|
|
---
|
|
|
|
### `getAudits(params)`
|
|
|
|
Retrieve audit records from the zero-knowledge archive. Uses the `archiveKey` for authentication.
|
|
|
|
```typescript
|
|
type GetAuditsParams = {
|
|
agreementId?: string; // Optional: falls back to init() defaults.agreementId
|
|
eventId?: string; // Optional: lookup audits for a specific event
|
|
meta?: Record<string, unknown>; // Optional: lookup audits by meta keys (AND logic)
|
|
};
|
|
|
|
getAudits(params: GetAuditsParams): Promise<{ auditRecords: AuditRecord[], ... }>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
// Get all audits for an agreement
|
|
const audits = await getAudits({ agreementId: "58810f16-b976-41f0-9566-2c26f174b592" });
|
|
|
|
// Get audits for a specific event
|
|
const eventAudits = await getAudits({ eventId: "evt-12345" });
|
|
|
|
// Get audits by custom meta ID
|
|
const metaAudits = await getAudits({ meta: { myCustomId: "unique-456" } });
|
|
```
|
|
|
|
---
|
|
|
|
### `verifyAudit(params)`
|
|
|
|
Verify the integrity of audit records against the local data store. Returns arrays of `valid` and `invalid` records with detailed validation results.
|
|
|
|
```typescript
|
|
type VerifyAuditParams = {
|
|
audits: AuditRecord[]; // Audit records to verify
|
|
shortNames: string[]; // Entity short names that signed the records
|
|
};
|
|
|
|
type AuditResult = {
|
|
audit: AuditRecord;
|
|
results: {
|
|
validId: boolean; // Event ID matches local data store
|
|
validSignature: boolean; // Cryptographic signature is valid
|
|
validAuditHash: boolean; // Audit hash matches stored data
|
|
validAuditSignature: boolean; // Audit record signature is valid
|
|
validMatchingDids: boolean; // Signing DIDs match target object
|
|
validEventAgreement: boolean; // Event signing DIDs signed the governing agreement
|
|
validEventAgreementSignature: boolean; // Agreement signatures are valid
|
|
};
|
|
};
|
|
|
|
verifyAudit(params: VerifyAuditParams): Promise<{ valid: AuditResult[], invalid: AuditResult[] }>;
|
|
```
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
const audits = await getAudits({ agreementId: agreement.created.agreementId });
|
|
|
|
const result = await verifyAudit({
|
|
audits: audits.auditRecords || [],
|
|
shortNames: [
|
|
"alice@test.jlinc.io",
|
|
"bob@test.jlinc.io",
|
|
],
|
|
});
|
|
|
|
console.log(result.valid.length); // Number of valid records
|
|
console.log(result.invalid.length); // Number of tampered/invalid records
|
|
```
|
|
|
|
## Validation Result Fields
|
|
|
|
When `verifyAudit` returns results, each boolean field means:
|
|
|
|
| Field | Description |
|
|
|-------|-------------|
|
|
| `validId` | The event ID in the audit record matches the local data store. |
|
|
| `validSignature` | The cryptographic signature on the stored data is valid. |
|
|
| `validAuditHash` | The hash in the audit record is a valid representation of stored data. |
|
|
| `validAuditSignature` | The cryptographic signature on the audit record is valid. |
|
|
| `validMatchingDids` | The DIDs that signed the audit also signed the target object. |
|
|
| `validEventAgreement` | The DIDs that signed the audit signed the governing agreement. |
|
|
| `validEventAgreementSignature` | The signatures on the governing agreement are valid. |
|
|
|
|
Any record with a single `false` field is placed in the `invalid` array.
|
|
|
|
## Complete Workflow Example
|
|
|
|
```typescript
|
|
import {
|
|
init,
|
|
getDomains,
|
|
createEntity,
|
|
getEntity,
|
|
produceAgreement,
|
|
processAgreement,
|
|
getAgreement,
|
|
produceEvent,
|
|
getEvent,
|
|
processEvent,
|
|
getAudits,
|
|
verifyAudit,
|
|
auth,
|
|
} from "@jlinc/sdk";
|
|
|
|
// Step 0: Initialize
|
|
init({
|
|
apiKey: "your-api-key",
|
|
apiUrl: "https://api.jlinc.io",
|
|
archiveUrl: "https://api.jlinc.io",
|
|
archiveKey: "your-archive-key",
|
|
fedidUrl: "https://fedid.jlinc.io",
|
|
});
|
|
|
|
// Step 1: Create identities
|
|
const domains = await getDomains({
|
|
auth: {
|
|
subject: { type: "user", id: "admin" },
|
|
action: { name: "read" },
|
|
resource: { type: "data", id: "demo" },
|
|
},
|
|
});
|
|
|
|
const provider = await createEntity({
|
|
fedidUrl: "https://fedid.jlinc.io",
|
|
shortName: `provider@${domains[0]}`,
|
|
});
|
|
|
|
const user = await createEntity({
|
|
fedidUrl: "https://fedid.jlinc.io",
|
|
shortName: `user@${domains[0]}`,
|
|
});
|
|
|
|
// Step 2: Sign agreements
|
|
const agreement = await produceAgreement({
|
|
data: {
|
|
references: ["https://sisa.jlinc.org/v1/34020c5fb59ebc6507ebca4eb38090aec1097c6aec8d2ae2250ddfed4b4aa63c"],
|
|
permitted: ["data-sharing"],
|
|
prohibited: ["non-delegable"],
|
|
shortNames: [provider.didDoc.shortName],
|
|
validRoles: ["provider", "user", "third-party"],
|
|
},
|
|
shortName: provider.didDoc.shortName,
|
|
role: "provider",
|
|
});
|
|
|
|
await processAgreement({
|
|
agreementId: agreement.created.agreementId,
|
|
shortName: user.didDoc.shortName,
|
|
role: "user",
|
|
});
|
|
|
|
// Step 3: Exchange data
|
|
const event = await produceEvent({
|
|
type: "data",
|
|
senderShortName: user.didDoc.shortName,
|
|
recipientShortName: provider.didDoc.shortName,
|
|
agreementId: agreement.created.agreementId,
|
|
meta: { myCustomId: "session-abc" },
|
|
data: { query: "What is the weather?" },
|
|
});
|
|
|
|
await processEvent({
|
|
eventId: event.created.eventId,
|
|
shortName: provider.didDoc.shortName,
|
|
});
|
|
|
|
// Step 4: Audit and verify
|
|
const audits = await getAudits({ agreementId: agreement.created.agreementId });
|
|
|
|
const verification = await verifyAudit({
|
|
audits: audits.auditRecords || [],
|
|
shortNames: [user.didDoc.shortName, provider.didDoc.shortName],
|
|
});
|
|
```
|
|
|
|
## Nil Agreement
|
|
|
|
If JLINC is being used for zero-knowledge auditing only (no formal agreement), the nil agreement ID can be used:
|
|
|
|
```typescript
|
|
const event = await produceEvent({
|
|
type: "data",
|
|
senderShortName: "alice@test.jlinc.io",
|
|
recipientShortName: "bob@test.jlinc.io",
|
|
agreementId: "00000000-0000-0000-0000-000000000000", // Nil agreement
|
|
meta: { myCustomId: "audit-only-1" },
|
|
data: { query: "test" },
|
|
});
|
|
```
|
|
|
|
All subsequent operations (`getEvent`, `getAudits`, `verifyAudit`) work normally under the nil agreement.
|
|
|
|
## Fine-Grained Access Control with AuthZEN
|
|
|
|
Every API call can optionally include an `auth` parameter for AuthZEN-formatted authorization checks. If the subject lacks permission, the server returns `{ decision: false }`.
|
|
|
|
```typescript
|
|
// Check authorization before proceeding
|
|
const check = await auth({
|
|
subject: { type: "user", id: "myuser" },
|
|
action: { name: "read" },
|
|
resource: { type: "data", id: "1234", properties: { ownerID: "owner@test.com" } },
|
|
});
|
|
|
|
if (check.decision) {
|
|
// Authorized - proceed with the operation
|
|
}
|
|
```
|
|
|
|
## Environment Variables
|
|
|
|
The SDK does not load environment variables automatically. Use a library like `dotenv` in your application:
|
|
|
|
```typescript
|
|
import dotenv from "dotenv";
|
|
dotenv.config();
|
|
|
|
init({
|
|
apiKey: process.env.JLINC_API_KEY!,
|
|
apiUrl: process.env.JLINC_API_URL!,
|
|
archiveUrl: process.env.JLINC_ARCHIVE_URL!,
|
|
archiveKey: process.env.JLINC_ARCHIVE_KEY!,
|
|
fedidUrl: process.env.JLINC_FEDID_URL!,
|
|
});
|
|
```
|
|
|
|
## Type Exports
|
|
|
|
```typescript
|
|
export type {
|
|
AuthSubject,
|
|
AuthAction,
|
|
AuthResource,
|
|
AuthParams,
|
|
GetDomainsParams,
|
|
CreateEntityParams,
|
|
GetEntityParams,
|
|
ProduceAgreementParams,
|
|
ProcessAgreementParams,
|
|
GetAgreementParams,
|
|
ProduceEventParams,
|
|
GetEventParams,
|
|
ProcessEventParams,
|
|
GetAuditsParams,
|
|
VerifyAuditParams,
|
|
AuditResult,
|
|
};
|
|
|
|
export {
|
|
init,
|
|
auth,
|
|
getDomains,
|
|
createEntity,
|
|
getEntity,
|
|
produceAgreement,
|
|
processAgreement,
|
|
getAgreement,
|
|
produceEvent,
|
|
getEvent,
|
|
processEvent,
|
|
getAudits,
|
|
verifyAudit,
|
|
};
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The SDK uses JavaScript `Promise` rejection for network errors and non-2xx responses. Wrap calls in `try/catch` blocks:
|
|
|
|
```typescript
|
|
try {
|
|
const agreement = await produceAgreement({
|
|
data: { permitted: ["data-sharing"] },
|
|
shortName: "my-entity@domain.tld",
|
|
role: "provider",
|
|
});
|
|
} catch (error) {
|
|
if (error.response) {
|
|
// Server responded with an error status
|
|
console.error(error.response.status, error.response.data);
|
|
} else if (error.request) {
|
|
// Request was made but no response received
|
|
console.error("No response from server");
|
|
} else {
|
|
// Something else went wrong
|
|
console.error(error.message);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Documentation
|
|
|
|
Full usage guide: [docs.jlinc.io/usage-guide](https://docs.jlinc.io)
|