-
Notifications
You must be signed in to change notification settings - Fork 0
SDK JavaScript Guide
Official JavaScript/TypeScript SDK for the Credenxia Digital Wallet and Verifiable Credentials platform.
- 🌐 Browser & Node.js - Works in browsers and Node.js environments
- 📝 TypeScript First - Full TypeScript support with complete type definitions
- 🔒 WebCrypto API - Native browser cryptography for security
- 📦 Tree-Shakeable - Only bundle what you use
- 🔄 Real-time Updates - WebSocket support for live updates
- 🧩 Framework Agnostic - Works with React, Vue, Angular, or vanilla JS
- 🎣 React Hooks - Optional React hooks for easy integration
npm install @credenxia/sdk
yarn add @credenxia/sdk
pnpm add @credenxia/sdk
<!-- UMD build -->
<script src="https://unpkg.com/@credenxia/sdk@latest/dist/credenxia.umd.js"></script>
<!-- ES Module -->
<script type="module">
import { CredenxiaClient } from 'https://unpkg.com/@credenxia/sdk@latest/dist/credenxia.esm.js';
</script>
import { CredenxiaClient, CredenxiaConfig } from '@credenxia/sdk';
// Initialize the client
const client = new CredenxiaClient({
apiKey: 'your-api-key',
environment: 'production',
baseUrl: 'https://api.credenxia.gov.au'
});
// Create a wallet
async function createWallet() {
try {
const wallet = await client.wallets.create({
userId: 'user-123',
type: 'personal'
});
console.log('Wallet created:', wallet.did);
return wallet;
} catch (error) {
console.error('Error creating wallet:', error);
throw error;
}
}
const { CredenxiaClient } = require('@credenxia/sdk');
// Initialize the client
const client = new CredenxiaClient({
apiKey: 'your-api-key',
environment: 'production'
});
// Create a wallet
async function createWallet() {
try {
const wallet = await client.wallets.create({
userId: 'user-123',
type: 'personal'
});
console.log('Wallet created:', wallet.did);
return wallet;
} catch (error) {
console.error('Error creating wallet:', error);
throw error;
}
}
import React from 'react';
import { CredenxiaProvider, useCredenxia } from '@credenxia/sdk/react';
// Wrap your app with the provider
function App() {
return (
<CredenxiaProvider
config={{
apiKey: process.env.REACT_APP_CREDENXIA_API_KEY,
environment: 'production'
}}
>
<WalletManager />
</CredenxiaProvider>
);
}
// Use hooks in components
function WalletManager() {
const { client, isReady } = useCredenxia();
const [wallet, setWallet] = React.useState(null);
const [loading, setLoading] = React.useState(false);
const createWallet = async () => {
if (!isReady) return;
setLoading(true);
try {
const newWallet = await client.wallets.create({
userId: 'current-user',
type: 'personal'
});
setWallet(newWallet);
} catch (error) {
console.error('Failed to create wallet:', error);
} finally {
setLoading(false);
}
};
return (
<div>
{wallet ? (
<div>Wallet DID: {wallet.did}</div>
) : (
<button onClick={createWallet} disabled={loading}>
{loading ? 'Creating...' : 'Create Wallet'}
</button>
)}
</div>
);
}
import { useWallet, useCredentials, useVerification } from '@credenxia/sdk/react';
function CredentialManager() {
const { wallet, loading: walletLoading } = useWallet('user-123');
const { credentials, fetchCredentials } = useCredentials(wallet?.id);
const { verify, verifying, result } = useVerification();
const handleVerification = async (credentialId: string) => {
const credential = credentials.find(c => c.id === credentialId);
if (credential) {
await verify(credential);
}
};
// Component logic...
}
<template>
<div>
<button @click="createWallet" :disabled="loading">
{{ loading ? 'Creating...' : 'Create Wallet' }}
</button>
<div v-if="wallet">
Wallet DID: {{ wallet.did }}
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { CredenxiaClient } from '@credenxia/sdk';
const client = new CredenxiaClient({
apiKey: import.meta.env.VITE_CREDENXIA_API_KEY,
environment: 'production'
});
const wallet = ref(null);
const loading = ref(false);
const createWallet = async () => {
loading.value = true;
try {
wallet.value = await client.wallets.create({
userId: 'current-user',
type: 'personal'
});
} catch (error) {
console.error('Failed to create wallet:', error);
} finally {
loading.value = false;
}
};
</script>
import { Injectable } from '@angular/core';
import { CredenxiaClient, Wallet, Credential } from '@credenxia/sdk';
import { Observable, from } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class WalletService {
private client: CredenxiaClient;
constructor() {
this.client = new CredenxiaClient({
apiKey: environment.credenxiaApiKey,
environment: 'production'
});
}
createWallet(userId: string): Observable<Wallet> {
return from(this.client.wallets.create({
userId,
type: 'personal'
}));
}
getCredentials(walletId: string): Observable<Credential[]> {
return from(this.client.credentials.list({
walletId
}));
}
}
// Enable WebSocket connection
const client = new CredenxiaClient({
apiKey: 'your-api-key',
enableWebSocket: true
});
// Subscribe to wallet events
client.on('wallet.created', (wallet) => {
console.log('New wallet created:', wallet);
});
client.on('credential.issued', (credential) => {
console.log('New credential issued:', credential);
});
client.on('credential.revoked', ({ credentialId, reason }) => {
console.log(`Credential ${credentialId} revoked: ${reason}`);
});
// Unsubscribe when done
client.off('wallet.created');
import { CredenxiaClient, OfflineStorage } from '@credenxia/sdk';
// Enable offline support
const client = new CredenxiaClient({
apiKey: 'your-api-key',
offline: {
enabled: true,
storage: new OfflineStorage({
dbName: 'credenxia-offline',
version: 1
})
}
});
// Works offline - data syncs when online
const credentials = await client.credentials.list({
walletId: 'wallet-123'
});
// Check sync status
client.offline.on('sync:start', () => {
console.log('Syncing with server...');
});
client.offline.on('sync:complete', (result) => {
console.log(`Synced ${result.count} items`);
});
import { CryptoService } from '@credenxia/sdk/crypto';
const crypto = new CryptoService();
// Generate key pair
const keyPair = await crypto.generateKeyPair('ECDSA', 'P-256');
// Sign data
const signature = await crypto.sign(
data,
keyPair.privateKey,
{ algorithm: 'ECDSA' }
);
// Verify signature
const isValid = await crypto.verify(
data,
signature,
keyPair.publicKey
);
// Encrypt/Decrypt
const encrypted = await crypto.encrypt(data, publicKey);
const decrypted = await crypto.decrypt(encrypted, privateKey);
import { QRCodeService } from '@credenxia/sdk/qr';
const qrService = new QRCodeService();
// Generate QR code for presentation request
const presentationRequest = {
challenge: 'random-challenge',
requestedCredentials: ['DriversLicense']
};
const qrCodeDataUrl = await qrService.generate(presentationRequest);
// Display QR code
document.getElementById('qr-code').src = qrCodeDataUrl;
// Scan QR code (requires camera permission)
const scanner = await qrService.createScanner();
scanner.on('scan', async (data) => {
const presentation = await client.presentations.parse(data);
console.log('Scanned presentation:', presentation);
});
scanner.start(document.getElementById('camera-preview'));
import type {
Wallet,
Credential,
VerifiablePresentation,
VerificationResult,
IssuerProfile,
TrustRegistry
} from '@credenxia/sdk';
// Strongly typed API responses
const wallet: Wallet = await client.wallets.create({
userId: 'user-123',
type: 'personal'
});
// Type guards
if (isCredential(data)) {
// data is typed as Credential
console.log(data.credentialSubject);
}
// Generic types for custom claims
interface CustomClaims {
firstName: string;
lastName: string;
dateOfBirth: string;
}
const credential = await client.credentials.issue<CustomClaims>({
walletId: wallet.id,
type: 'CustomCredential',
subject: {
firstName: 'John',
lastName: 'Doe',
dateOfBirth: '1990-01-01'
}
});
// Extend SDK types
interface ExtendedWallet extends Wallet {
customField: string;
}
// Type-safe configuration
const config: CredenxiaConfig = {
apiKey: process.env.API_KEY!,
environment: 'production',
retry: {
maxAttempts: 3,
backoffMultiplier: 2
},
cache: {
enabled: true,
ttl: 300000 // 5 minutes
}
};
import {
CredenxiaError,
NetworkError,
ValidationError,
AuthenticationError
} from '@credenxia/sdk/errors';
try {
await client.wallets.create({ userId: 'user-123' });
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.errors);
} else if (error instanceof AuthenticationError) {
console.error('Authentication failed:', error.message);
// Redirect to login
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
// Retry or show offline message
} else if (error instanceof CredenxiaError) {
console.error('SDK error:', error.code, error.message);
} else {
console.error('Unknown error:', error);
}
}
import { CredenxiaClient } from '@credenxia/sdk';
import { mockClient } from '@credenxia/sdk/testing';
describe('WalletService', () => {
let client: CredenxiaClient;
beforeEach(() => {
client = mockClient();
});
test('creates wallet successfully', async () => {
const wallet = await client.wallets.create({
userId: 'test-user',
type: 'personal'
});
expect(wallet).toBeDefined();
expect(wallet.did).toMatch(/^did:credenxia:/);
});
});
import { test, expect } from '@playwright/test';
test('wallet creation flow', async ({ page }) => {
await page.goto('/wallet/create');
// Fill form
await page.fill('[name="userId"]', 'test-user');
await page.selectOption('[name="type"]', 'personal');
// Submit
await page.click('button[type="submit"]');
// Wait for wallet creation
await page.waitForSelector('[data-testid="wallet-did"]');
const did = await page.textContent('[data-testid="wallet-did"]');
expect(did).toMatch(/^did:credenxia:/);
});
// Lazy load heavy features
const QRScanner = lazy(() => import('@credenxia/sdk/qr'));
const CryptoService = lazy(() => import('@credenxia/sdk/crypto'));
// Use when needed
async function scanQRCode() {
const { QRCodeScanner } = await import('@credenxia/sdk/qr');
const scanner = new QRCodeScanner();
// ...
}
const client = new CredenxiaClient({
apiKey: 'your-api-key',
cache: {
enabled: true,
strategy: 'memory', // or 'localStorage', 'sessionStorage'
ttl: 5 * 60 * 1000, // 5 minutes
maxSize: 50 // Maximum cached items
}
});
// Force cache refresh
await client.credentials.list({ walletId: 'wallet-123' }, {
cache: 'reload'
});
Browser | Version |
---|---|
Chrome | 90+ |
Firefox | 88+ |
Safari | 14+ |
Edge | 90+ |
Opera | 76+ |
// For older browsers, include polyfills
import '@credenxia/sdk/polyfills';
// Or selectively import what you need
import '@credenxia/sdk/polyfills/webcrypto';
import '@credenxia/sdk/polyfills/indexeddb';
Package | Size (minified) | Size (gzipped) |
---|---|---|
Core | 45 KB | 12 KB |
React | 8 KB | 3 KB |
Crypto | 15 KB | 5 KB |
QR | 25 KB | 8 KB |
Full | 93 KB | 28 KB |
// Old (v0.x)
import Credenxia from 'credenxia-sdk';
const sdk = new Credenxia('api-key');
const wallet = await sdk.createWallet('user-123');
// New (v1.0)
import { CredenxiaClient } from '@credenxia/sdk';
const client = new CredenxiaClient({ apiKey: 'api-key' });
const wallet = await client.wallets.create({
userId: 'user-123',
type: 'personal'
});
Full API documentation: https://docs.credenxia.gov.au/sdk/javascript
- Documentation: https://docs.credenxia.gov.au
- npm Package: https://www.npmjs.com/package/@credenxia/sdk
- GitHub: https://github.com/credenxia/javascript-sdk
- Discord: https://discord.gg/credenxia
- Email: sdk-support@credenxia.gov.au
This SDK is proprietary software. See LICENSE file for details.
We welcome contributions! Please see our Contributing Guide.
See CHANGELOG.md for version history.
Built with TypeScript for modern web applications 🚀
Tender Reference: DPC2142 | Version: 2.0 FINAL | Date: 09/09/2025
Home • Architecture • Security • APIs • SDKs • Support
Client: Department of the Premier and Cabinet (DGov), Western Australia
Solution: Credenxia v2 Platform
Phase: Proof-of-Operation → Pilot → Production
Infrastructure: Azure Australia (Perth Extended Zone - 2025)
Company: Credenxia Pty Ltd
ABN: [To be provided]
Location: Perth, Western Australia
Contact: support@credenxia.com
✓ ISO/IEC 18013-5/7 • ✓ ISO/IEC 23220 • ✓ W3C VC 2.0 • ✓ TDIF Compliant
✓ Australian Privacy Act • ✓ GDPR Ready • ✓ ISO 27001 (Roadmap)
All data remains within Australian sovereign boundaries
Zero-knowledge proofs • Selective disclosure • End-to-end encryption
© 2025 Credenxia Pty Ltd. All rights reserved. | Confidential and Proprietary | Privacy Policy | Terms of Service
- Pricing & Assumptions
- Consumption Pricing Justification
- Detailed Cost Breakdown
- Tender Submission Assumptions
- Azure Justification
- Azure Calculator Guide
Use GitHub's search feature above to find specific topics