A platform-agnostic TypeScript API client for Sovereign Network ZHTP nodes. Provides unified access to identity, wallet, DAO, smart contract, and blockchain operations across Electron, React Native, and web/Node.js environments with a single codebase.
- Platform-Agnostic Core: Single codebase works across Electron, React Native, and vanilla JavaScript/Node.js
- 52 API Methods: Complete coverage of identity, wallet, DAO, smart contracts, Web4, blockchain, and zero-knowledge operations
- Full TypeScript Support: Comprehensive type definitions with strict mode enabled
- Built-in Retry Logic: Automatic exponential backoff for reliable requests
- Environment-Specific Config: Platform-specific configuration providers for Electron IPC, React Native AsyncStorage, and browser localStorage
- Type Safety: Full TypeScript support with strict mode enabled
- Error Handling: Graceful error handling with fallbacks
npm install @sovereign-network/api-clientThat's it. The package is public on GitHub Packages - no authentication required.
import { ZhtpApi, ElectronConfigProvider } from '@sovereign-network/api-client/electron';
// Main process: expose config via IPC
import { ipcMain } from 'electron';
ipcMain.handle('get-config', async () => ({
zhtpNodeUrl: process.env.ZHTP_NODE_URL || 'http://localhost:8000',
networkType: 'testnet',
debugMode: false,
enableBiometrics: true,
}));
// Renderer process: use the API
const configProvider = new ElectronConfigProvider();
const api = new ZhtpApi(configProvider);
await api.ensureInitialized();
const proposals = await api.getDaoProposals();
const balance = await api.getWalletBalance(did);import { ZhtpApi, ReactNativeConfigProvider } from '@sovereign-network/api-client/react-native';
const configProvider = new ReactNativeConfigProvider({
ZHTP_NODE_URL: 'http://192.168.1.100:8000',
NETWORK_TYPE: 'testnet',
DEBUG_MODE: __DEV__,
ENABLE_BIOMETRICS: true,
});
const api = new ZhtpApi(configProvider);
await api.ensureInitialized();
const identity = await api.signIn(did, passphrase);
const balance = await api.getWalletBalance(identity.did);import { ZhtpApi, BrowserConfigProvider } from '@sovereign-network/api-client';
// Server should expose /api/config endpoint
const configProvider = new BrowserConfigProvider();
const api = new ZhtpApi(configProvider);
await api.ensureInitialized();
const dapp = await api.resolveDomain('example.web4');
const content = await api.loadWeb4Resource('example.web4/index.html');┌─────────────────────────────────────────────────────────┐
│ Electron Renderer │
│ ┌──────────────────────────────────────────────────┐ │
│ │ import ElectronConfigProvider from │ │
│ │ '@sovereign-network/api-client/electron' │ │
│ │ │ │
│ │ const configProvider = new │ │
│ │ ElectronConfigProvider() │ │
│ │ const api = new ZhtpApi(configProvider) │ │
│ └──────────────────────────────────────────────────┘ │
│ │ │
│ IPC: 'get-config' │
│ │ │
├─────────────────────────────────────────────────────────┤
│ Electron Main │
│ ┌──────────────────────────────────────────────────┐ │
│ │ ipcMain.handle('get-config', async () => ({ │ │
│ │ zhtpNodeUrl: ..., │ │
│ │ networkType: ..., │ │
│ │ debugMode: ..., │ │
│ │ enableBiometrics: ... │ │
│ │ })) │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
┌──────────┴──────────┐
│ │
ElectronConfigProvider ZhtpApi
│ │
└──────────┬──────────┘
│
ZHTP Node (HTTP)
┌────────────────────────────────────┐
│ React Native Application │
│ ┌──────────────────────────────┐ │
│ │ const configProvider = new │ │
│ │ ReactNativeConfigProvider( │ │
│ │ { ZHTP_NODE_URL: '...' } │ │
│ │ ) │ │
│ │ const api = new ZhtpApi(...) │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘
│
┌─────────┴──────────┐
│ │
AsyncStorage Environment Variables
│ │
└─────────┬──────────┘
│
ReactNativeConfigProvider
│
ZhtpApi
│
ZHTP Node (HTTP)
┌────────────────────────────────────┐
│ Browser/JavaScript │
│ ┌──────────────────────────────┐ │
│ │ const configProvider = new │ │
│ │ BrowserConfigProvider() │ │
│ │ const api = new ZhtpApi(...) │ │
│ └──────────────────────────────┘ │
└────────────────────────────────────┘
│
┌─────────┴──────────┐
│ │
localStorage /api/config
│ │
└─────────┬──────────┘
│
BrowserConfigProvider
│
ZhtpApi
│
ZHTP Node (HTTP)
signIn(did, passphrase)- Sign in with credentialscreateIdentity(data)- Create new identityrecoverIdentity(method, data)- Recover identity by method (seed/backup/social)recoverIdentityFromSeed(recoveryData)- Recover from seed phraserestoreIdentityFromBackup(backupData)- Restore from backuprecoverIdentityWithGuardians(guardianData)- Social recoverycreateZkDid(didData)- Create ZK-DIDgetIdentity(did)- Get identity detailsverifyIdentity(did, requirements)- Verify identity credentialscheckIdentityExists(identifier)- Check identity existencesignInWithIdentity(identity, passphrase)- Sign in with identity
getWallets(did)- Get all wallets for DIDgetWalletBalance(did)- Get wallet balancegetTransactionHistory(address, walletType)- Get transaction historygetAssets(address)- Get assets in walletsendTransaction(from, to, amount, metadata)- Send transaction
getDaoProposals()- Get all proposalsgetDaoStats()- Get DAO statisticsgetProposalDetails(proposalId)- Get specific proposal detailscreateProposal(proposal)- Create new proposalsubmitVote(proposalId, vote, voterDid)- Submit vote on proposalgetDaoData()- Get comprehensive DAO datagetDaoDelegates()- Get all delegatesgetDelegateProfile(delegateId)- Get delegate profileregisterDelegate(userDid, delegateInfo)- Register as delegaterevokeDelegation(userDid)- Revoke delegationgetTreasuryHistory()- Get treasury transaction historycreateSpendingProposal(proposalData)- Create spending proposalgetVotingPower(userDid)- Get voting powergetUserVotes(userDid)- Get user's votesgetDaoTreasury()- Get DAO treasury balance
deployContract(contractId, bytecode, metadata)- Deploy contractexecuteContract(contractId, functionName, args)- Execute contract functionqueryContract(contractId, functionName, args)- Query contract stategetContractMetadata(contractId)- Get contract metadataupgradeContract(contractId, bytecode, metadata)- Upgrade contract
resolveDomain(domainName)- Resolve domain to contractloadWeb4Resource(url)- Load Web4 resource contentresolveDapp(domain)- Resolve DApp by domaingetContractContent(contractId, path)- Get contract content by pathgetContractByHash(hash)- Get contract by blockchain hashgetContractById(contractId)- Get contract by ID
getBlockchainInfo()- Get blockchain informationgetGasInfo()- Get gas pricing informationgetNodeStatus()- Get node statusgetMeshPeers()- Get mesh network peersgetNetworkStats()- Get network statisticsgetNetworkInfo()- Get network information
generateZkProof(data)- Generate ZK proofverifyZkProof(proof)- Verify ZK proof
testConnection()- Test connection to nodeensureInitialized()- Ensure API is initializedgetProtocolInfo()- Get protocol information
The ElectronConfigProvider reads from Electron IPC.
preload.ts:
import { contextBridge, ipcRenderer } from 'electron';
contextBridge.exposeInMainWorld('electronAPI', {
getConfig: () => ipcRenderer.invoke('get-config'),
});main.ts:
import { ipcMain } from 'electron';
ipcMain.handle('get-config', async () => {
return {
zhtpNodeUrl: process.env.ZHTP_NODE_URL || 'http://localhost:8000',
networkType: process.env.NETWORK_TYPE || 'testnet',
debugMode: process.env.DEBUG_MODE === 'true',
enableBiometrics: true,
};
});Environment variables in order of precedence:
- Constructor
envVarsparameter process.env(if available)- AsyncStorage cache
- Defaults
const configProvider = new ReactNativeConfigProvider({
ZHTP_NODE_URL: 'http://192.168.1.100:8000',
NETWORK_TYPE: 'testnet',
DEBUG_MODE: __DEV__,
ENABLE_BIOMETRICS: true,
});Also supports dynamic updates:
await configProvider.updateConfig({ zhtpNodeUrl: 'http://new-node:8000' });
await configProvider.clearCache();Configuration sources in order:
- localStorage (cache)
- API endpoint
/api/config - Defaults
Server endpoint:
app.get('/api/config', (req, res) => {
res.json({
zhtpNodeUrl: process.env.ZHTP_NODE_URL || 'http://localhost:8000',
networkType: 'testnet',
debugMode: false,
enableBiometrics: true,
});
});- Exponential backoff: 1s → 2s → 4s delays
- Max 3 retries on network errors
- Does NOT retry on 4xx client errors
- Automatic error recovery
- 30-second request timeout
- AbortController-based cancellation
- Proper cleanup on timeout
- Full TypeScript strict mode
- Comprehensive type definitions
- All methods fully typed
initPromisetracks async setupensureInitialized()waits for config load- Connection state tracking
try {
const proposals = await api.getDaoProposals();
} catch (error) {
console.error('Failed:', error.message);
// Error already retried up to 3 times with exponential backoff
}npm run buildnpm run type-checknpm testnpm run test:coveragenpm run devnpm run prepare # type-check + build + tests all at oncePublishing is automated via GitHub Actions on every push to main:
-
Commit with semantic messages:
fix:→ patch version (1.0.0 → 1.0.1)feat:→ minor version (1.0.0 → 1.1.0)BREAKING CHANGE:→ major version (1.0.0 → 2.0.0)
-
Push to main:
git push origin main
-
Automated workflow:
- Analyzes commits
- Bumps version
- Creates CHANGELOG
- Publishes to GitHub Packages
- Creates GitHub release
- Commits back to repo
No manual steps needed!
src/
├── core/ # Platform-agnostic core
│ ├── types.ts # Type definitions
│ ├── config-provider.ts # Config interface
│ ├── zhtp-api.ts # Main API class
│ ├── zhtp-api-methods.ts # 52 API methods
│ └── zhtp-api-core.ts # Retry & request logic
│
├── electron/ # Electron entry point
│ ├── config-provider.ts # IPC-based config
│ └── index.ts # Exports
│
├── react-native/ # React Native entry point
│ ├── config-provider.ts # AsyncStorage config
│ └── index.ts # Exports
│
└── vanilla-js/ # Browser entry point
├── config-provider.ts # localStorage config
└── index.ts # Exports
- Total Tests: 170 (all passing ✓)
- Overall Coverage: 80.72%
- Retry Logic: 92.85%
- Config Providers: 96-97% each
- API Methods: 86.36%
- Single Fetch API: Uses standard
fetch()in all environments - Platform Abstraction: Config providers handle platform differences
- Type Safety: Full TypeScript with strict mode
- Resilience: Automatic retry with exponential backoff
- Isomorphic: Same code runs everywhere
All types are exported and fully typed:
import type {
Identity,
Wallet,
DaoProposal,
DaoStats,
Transaction,
Delegate,
ProposalDetails,
SmartContract,
ContractDeploymentResult,
Asset,
NodeStatus,
GasInfo,
Proof,
ApiConfig,
ConfigProvider,
} from '@sovereign-network/api-client';MIT
Contributions welcome! Ensure:
- All TypeScript compiles with strict mode
- All tests pass (
npm test) - Types are properly exported
- No additional markdown files