npm package: @flowhash/nftc-client
Description: TypeScript client SDK for NFTC Protocol Registry API
Author: NFTC Protocol Client Team
Latest version: 0.1.0

# NFTC Protocol Client SDK

A comprehensive TypeScript client SDK for the NFTC Protocol Registry API. Provides type-safe, promise-based access to credential issuance, verification, settlement, and GDPR operations.

## Features

- **Full API Coverage**: Complete implementation of all NFTC Registry endpoints
- **Type-Safe**: 100% TypeScript with full type definitions
- **Error Handling**: Custom error classes for different failure scenarios
- **Request Retry Logic**: Automatic retries with exponential backoff
- **Token Management**: Built-in JWT authentication and token refresh
- **Correlation Tracking**: Request tracking across distributed systems
- **Interceptors**: Request/response interceptors for logging and preprocessing
- **Browser Compatible**: Works in both Node.js and browser environments
- **Zero Dependencies**: Only requires axios for HTTP requests

## Installation

```bash
npm install @flowhash/nftc-client axios
```

Or with yarn:

```bash
yarn add @flowhash/nftc-client axios
```

## Quick Start

### Basic Initialization

```typescript
import { NFTCClient } from '@flowhash/nftc-client';

const client = new NFTCClient({
  baseURL: 'https://api.nftcprotocol.org',
  apiKey: 'your-api-key',
  timeout: 30000,
  retryAttempts: 3
});
```

### Issue a Right-to-Use Credential

```typescript
const rtu = await client.credentials.issueRTU({
  holderDid: 'did:example:user123',
  resourceId: 'asset:forklift:FL-001',
  resourceType: 'equipment',
  validFrom: '2024-01-01T00:00:00Z',
  validUntil: '2024-12-31T23:59:59Z',
  usagePolicy: {
    maxHours: 160,
    geofence: {
      type: 'circle',
      coordinates: [40.7128, -74.0060],
      radius: 5
    }
  }
});

console.log('RTU issued:', rtu.id);
```

### Record Proof-of-Use

```typescript
const pou = await client.credentials.issueProofOfUse({
  holderDid: 'did:example:user123',
  rtuReference: rtu.id,
  resourceId: 'asset:forklift:FL-001',
  startTime: '2024-01-15T08:00:00Z',
  endTime: '2024-01-15T16:00:00Z',
  metering: {
    hoursUsed: 8,
    distanceTraveled: 45.5,
    fuelConsumed: 12.3
  }
});

console.log('Usage recorded:', pou.id);
```

### Verify a Credential

```typescript
const result = await client.verify.verifyCredential(rtu.id);

if (result.valid) {
  console.log('Credential is valid');
  console.log('Signature valid:', result.checks.signatureValid);
  console.log('Schema valid:', result.checks.schemaValid);
} else {
  console.log('Verification failed:', result.errors);
}
```

### Record Contributions and Settle

```typescript
// Record a contribution
const contribution = await client.settlement.recordContribution({
  contributorDid: 'did:example:worker123',
  contributionType: 'labor',
  projectId: 'project:renovation:2024',
  valueUnits: 40,
  valueMetric: 'hours',
  period: {
    start: '2024-01-01T00:00:00Z',
    end: '2024-01-31T23:59:59Z'
  },
  description: 'Electrical installation work'
});

// Close settlement
const receipt = await client.settlement.closeSettlement({
  participantDid: 'did:example:worker123',
  settlementId: 'settlement:proj2024:q1',
  contributions: [contribution.id],
  totalValue: 3000,
  currency: 'USD',
  breakdown: [{
    contributionId: contribution.id,
    valueUnits: 40,
    valueMetric: 'hours',
    rate: 75,
    compensationAmount: 3000
  }],
  paymentMethod: 'bank_transfer'
});

console.log('Settlement closed:', receipt.settlementId);
```

## Authentication

### Challenge-Response Authentication

```typescript
import { signData } from '@flowhash/nftc-core';

// Get challenge
const challenge = await client.auth.getAuthChallenge(did);

// Sign challenge with your private key
const signature = await signData(challenge.challenge, privateKey);

// Login
const token = await client.auth.login(did, signature);

// Set token for subsequent requests
client.setAuthToken(token.accessToken);

// Setup automatic token refresh
client.setRefreshTokenFunction(async (refreshToken) => {
  const newToken = await client.auth.refreshToken(refreshToken);
  return newToken.accessToken;
});
```

### Validate and Revoke Tokens

```typescript
// Check if token is valid
const validation = await client.auth.validateToken(token);
console.log('Token valid:', validation.valid);

// Revoke token
await client.auth.revokeToken(token);

// Logout session
await client.auth.logout(did);
```

## Credential Management

### List Credentials

```typescript
// Get paginated list of credentials for a holder
const page = await client.credentials.listCredentials(
  'did:example:user123',
  limit: 50,
  offset: 0
);

console.log('Total credentials:', page.total);
console.log('Retrieved:', page.credentials.length);

// Process paginated results
for (let offset = 0; offset < page.total; offset += 50) {
  const page = await client.credentials.listCredentials(
    did,
    50,
    offset
  );
  // Process page
}
```

### Get Specific Credential

```typescript
const credential = await client.credentials.getCredential('did:nftc:rtu:xyz123');
console.log('Holder:', credential.credentialSubject.id);
console.log('Resource:', credential.credentialSubject.resourceId);
```

### Revoke Credential

```typescript
const result = await client.credentials.revokeCredential(
  'did:nftc:rtu:xyz123',
  'No longer needed'
);

console.log('Revoked at:', result.revokedAt);
```

### Export Credentials

```typescript
const exported = await client.credentials.exportCredentials(
  'did:example:user123',
  format: 'json-ld'
);

console.log('Exported credentials:', exported.credentials.length);
```

## Verification Operations

### Comprehensive Verification

```typescript
const result = await client.verify.verifyCredential(credentialId);

console.log('Overall valid:', result.valid);
console.log('Checks:');
console.log('  - Signature:', result.checks.signatureValid);
console.log('  - Inclusion proof:', result.checks.inclusionProofValid);
console.log('  - Temporal:', result.checks.temporallyValid);
console.log('  - Schema:', result.checks.schemaValid);
console.log('  - Invariants:', result.checks.invariantsValid);
```

### Specific Verification Checks

```typescript
// Verify signature
const sig = await client.verify.verifySignature(credentialId);
console.log('Signature valid:', sig.signatureValid);

// Check temporal validity
const temporal = await client.verify.checkTemporalValidity(credentialId);
console.log('Currently valid:', temporal.isCurrentlyValid);

// Verify inclusion proof
const inclusion = await client.verify.verifyInclusionProof(credentialId);
console.log('Anchor valid:', inclusion.inclusionProofValid);

// Check schema compliance
const schema = await client.verify.verifySchemaCompliance(credentialId);
console.log('Schema compliant:', schema.compliant);

// Verify invariants
const invariants = await client.verify.verifyInvariants(credentialId);
console.log('Invariants valid:', invariants.invariantsValid);
```

### Batch Verification

```typescript
const credentialIds = [
  'did:nftc:rtu:123',
  'did:nftc:poc:456',
  'did:nftc:settlement:789'
];

const results = await client.verify.verifyCredentialsInBatch(credentialIds);
results.forEach((result, index) => {
  console.log(`Credential ${index + 1}:`, result.valid ? 'valid' : 'invalid');
});
```

### Get Verification Status

```typescript
const status = await client.verify.getVerificationStatus(credentialId);
console.log('Status:', status.status); // 'valid', 'invalid', 'revoked', 'expired', 'pending'
console.log('Last verified:', status.lastVerified);
```

## Settlement Management

### Record Contributions

```typescript
// Labor contribution
const labor = await client.settlement.recordContribution({
  contributorDid: 'did:example:worker123',
  contributionType: 'labor',
  projectId: 'project:renovation:2024',
  valueUnits: 40,
  valueMetric: 'hours',
  period: '2024-01-01T00:00:00Z/2024-01-31T23:59:59Z',
  description: 'Electrical work'
});

// Material contribution
const materials = await client.settlement.recordContribution({
  contributorDid: 'did:example:supplier456',
  contributionType: 'resource',
  projectId: 'project:renovation:2024',
  valueUnits: 5000,
  valueMetric: 'units',
  period: {
    start: '2024-01-01T00:00:00Z',
    end: '2024-01-31T23:59:59Z'
  },
  description: 'Electrical materials'
});

// Equipment contribution
const equipment = await client.settlement.recordContribution({
  contributorDid: 'did:example:equipment-owner',
  contributionType: 'equipment',
  projectId: 'project:renovation:2024',
  valueUnits: 10,
  valueMetric: 'days',
  period: {
    start: '2024-01-01T00:00:00Z',
    end: '2024-01-31T23:59:59Z'
  }
});
```

### List Contributions

```typescript
const contributions = await client.settlement.listContributions(
  'project:renovation:2024',
  limit: 50,
  offset: 0
);

console.log('Total contributions:', contributions.total);
contributions.contributions.forEach(contrib => {
  console.log(`${contrib.credentialSubject.contributionType}: ${contrib.credentialSubject.valueUnits} ${contrib.credentialSubject.valueMetric}`);
});
```

### Close Settlement

```typescript
const settlement = await client.settlement.closeSettlement({
  participantDid: 'did:example:worker123',
  settlementId: 'settlement:proj2024:q1',
  contributions: [labor.id, equipment.id],
  totalValue: 3750,
  currency: 'USD',
  breakdown: [
    {
      contributionId: labor.id,
      valueUnits: 40,
      valueMetric: 'hours',
      rate: 75,
      compensationAmount: 3000
    },
    {
      contributionId: equipment.id,
      valueUnits: 10,
      valueMetric: 'days',
      rate: 75,
      compensationAmount: 750
    }
  ],
  paymentMethod: 'bank_transfer',
  paymentReference: 'txn:wire:2024-01-31'
});

console.log('Settlement closed');
console.log('Total compensation:', settlement.totalValue, settlement.currency);
```

### Get Settlement Summary

```typescript
const summary = await client.settlement.getSettlementSummary(
  'did:example:org123',
  '2024-01-01T00:00:00Z',
  '2024-01-31T23:59:59Z'
);

console.log('Q1 2024 Summary:');
console.log('  Total settlements:', summary.totalSettlements);
console.log('  Total contributions:', summary.totalContributions);
console.log('  Total compensation:', summary.totalCompensation, summary.currency);
```

## GDPR Operations

### Export Personal Data

```typescript
// Full export
const data = await client.gdpr.exportData('did:example:user123', 'json');
console.log('Credentials:', data.credentials.length);
console.log('Transactions:', data.transactions.length);

// Export specific credential types
const rtuOnly = await client.gdpr.exportCredentialsByType(
  'did:example:user123',
  ['RightToUse']
);

// Export date range
const january = await client.gdpr.exportCredentialsByDateRange(
  'did:example:user123',
  '2024-01-01T00:00:00Z',
  '2024-01-31T23:59:59Z'
);
```

### Check GDPR Status

```typescript
const status = await client.gdpr.getGDPRStatus('did:example:user123');
console.log('Data held:', status.dataHeld);
console.log('Credentials:', status.credentialCount);
console.log('Last export:', status.lastExportDate);
```

### Delete Personal Data

```typescript
// Step 1: Request deletion token
const tokenResponse = await client.gdpr.requestDataDeletionToken('did:example:user123');
console.log('Token received, expires in', tokenResponse.expirationHours, 'hours');

// Step 2: Delete with confirmation (IRREVERSIBLE!)
const result = await client.gdpr.deleteData('did:example:user123', tokenResponse.token);
console.log('Data deleted at:', result.deletedAt);
```

### Manage Deletion Requests

```typescript
// List deletion requests
const requests = await client.gdpr.listDeletionRequests('did:example:user123');
requests.forEach(req => {
  console.log(`${req.id}: ${req.status}`);
});

// Cancel a deletion request
const cancelled = await client.gdpr.cancelDeletionRequest(
  'did:example:user123',
  'req_123'
);
console.log('Cancelled at:', cancelled.cancelledAt);
```

## Error Handling

### Catch Specific Errors

```typescript
import {
  ValidationError,
  AuthenticationError,
  NetworkError,
  NotFoundError,
  isNFTCError
} from '@flowhash/nftc-client';

try {
  await client.verify.verifyCredential('did:nftc:rtu:xyz123');
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Invalid request:', error.message);
  } else if (error instanceof AuthenticationError) {
    console.error('Authentication failed');
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
    console.error('Retry count:', error.retryCount);
  } else if (error instanceof NotFoundError) {
    console.error('Credential not found');
  } else if (isNFTCError(error)) {
    console.error('NFTC error:', error.code, error.message);
  } else {
    console.error('Unknown error:', error);
  }
}
```

### Available Error Classes

- `NFTCError` - Base error class
- `ValidationError` - Request validation failed
- `AuthenticationError` - Authentication failed (401)
- `AuthorizationError` - Insufficient permissions (403)
- `NetworkError` - Network request failed
- `NotFoundError` - Resource not found (404)
- `ConflictError` - Request conflict (409)
- `RateLimitError` - Rate limit exceeded (429)
- `ServerError` - Server error (5xx)
- `TimeoutError` - Request timeout
- `ParseError` - Response parsing failed

## Advanced Features

### Correlation ID Tracking

```typescript
// Set correlation ID for request tracing
client.setCorrelationId('trace-12345');

// Get current correlation ID
const traceId = client.getCorrelationId();
console.log('Tracing as:', traceId);

// All requests will include:
// X-Correlation-ID: trace-12345
```

### Custom Headers

```typescript
const client = new NFTCClient({
  baseURL: 'https://api.nftcprotocol.org',
  headers: {
    'X-Custom-Header': 'custom-value',
    'X-API-Version': 'v1'
  }
});
```

### Request Configuration

```typescript
const client = new NFTCClient({
  baseURL: 'https://api.nftcprotocol.org',
  timeout: 30000,           // 30 second timeout
  retryAttempts: 3,         // Retry failed requests 3 times
  retryDelay: 1000          // 1 second initial retry delay (exponential backoff)
});
```

## API Reference

### Credentials Endpoint (`client.credentials.*`)

- `issueRTU(params)` - Issue Right-to-Use credential
- `issueProofOfUse(params)` - Record Proof-of-Use credential
- `getCredential(id)` - Get credential by ID
- `listCredentials(did, limit, offset)` - List holder's credentials
- `revokeCredential(id, reason)` - Revoke credential
- `exportCredentials(did, format)` - Export credentials

### Settlement Endpoint (`client.settlement.*`)

- `recordContribution(params)` - Record Proof-of-Contribution
- `getContribution(id)` - Get contribution by ID
- `listContributions(projectId, limit, offset)` - List project contributions
- `closeSettlement(params)` - Close settlement and issue receipt
- `getSettlement(id)` - Get settlement by ID
- `listSettlements(did, limit, offset)` - List participant's settlements
- `getSettlementSummary(did, start, end)` - Get settlement summary

### Verification Endpoint (`client.verify.*`)

- `verifyCredential(id)` - Comprehensive credential verification
- `verifyCredentialData(credential)` - Verify credential object
- `verifyCredentialsInBatch(ids)` - Batch verification
- `verifySignature(id)` - Verify signature only
- `verifyInclusionProof(id)` - Verify Flowhash anchor
- `checkTemporalValidity(id)` - Check validity periods
- `verifySchemaCompliance(id)` - Verify JSON schema
- `verifyInvariants(id)` - Verify protocol invariants
- `getVerificationStatus(id)` - Get verification status

### GDPR Endpoint (`client.gdpr.*`)

- `exportData(did, format)` - Export all personal data
- `exportCredentialsByType(did, types)` - Export filtered by type
- `exportCredentialsByDateRange(did, start, end)` - Export by date range
- `deleteData(did, token)` - Delete all personal data
- `requestDataDeletionToken(did)` - Get deletion confirmation token
- `getGDPRStatus(did)` - Get GDPR compliance status
- `listDeletionRequests(did)` - List deletion requests
- `cancelDeletionRequest(did, requestId)` - Cancel pending deletion

### Authentication Endpoint (`client.auth.*`)

- `login(did, signature)` - Authenticate with signature
- `getAuthChallenge(did)` - Get challenge for signing
- `refreshToken(token)` - Refresh access token
- `validateToken(token)` - Check token validity
- `revokeToken(token)` - Revoke token
- `logout(did)` - Logout session
- `getAuthStatus(token)` - Get auth status
- `registerDID(did, document)` - Register new DID
- `isDIDRegistered(did)` - Check registration status

## Browser Support

This SDK works in modern browsers with ES2020+ support. For older browsers, use a transpiler like Babel.

```html
<script src="https://unpkg.com/@flowhash/nftc-client"></script>
<script>
  const client = new NFTC.NFTCClient({
    baseURL: 'https://api.nftcprotocol.org'
  });
</script>
```

## TypeScript Support

Full TypeScript support with type definitions included:

```typescript
import {
  NFTCClient,
  RightToUseCredential,
  VerificationResult,
  IssueRTUParams
} from '@flowhash/nftc-client';

// All types are exported for use in your code
const params: IssueRTUParams = { /* ... */ };
const credential: RightToUseCredential = await client.credentials.issueRTU(params);
const result: VerificationResult = await client.verify.verifyCredential(credential.id);
```

## Examples

See `/examples/basic-usage.ts` for comprehensive examples covering:
- Client initialization
- Authentication workflows
- Issuing credentials
- Recording proof-of-use
- Managing contributions and settlements
- Verifying credentials
- GDPR operations
- Error handling
- Pagination
- Correlation tracking

## Contributing

Contributions are welcome! Please ensure:
- All code is TypeScript with strict mode enabled
- Full JSDoc documentation on public APIs
- Comprehensive error handling
- 100% type coverage

## License

Apache 2.0 - See LICENSE file

## Support

For issues and feature requests, visit:
https://github.com/nftc-protocol/nftc-client/issues