Calimero Client SDKs
Client SDKs that let you interact with Calimero nodes from code using Python, Rust, or frontend stacks like Next.js, React, TypeScript, and Vite. Use them to build developer tools, monitoring, and automation around Calimero.
Overview
Section titled “Overview”Calimero provides client SDKs for different language ecosystems:
| SDK | Language | Repository | Primary Use Cases |
|---|---|---|---|
| Rust Client | Rust | core/crates/client | Sidecar tools, CLI utilities, developer tools |
| Python Client | Python | calimero-client-py | Automation scripts, monitoring tools, developer tools |
| mero-js | TypeScript | mero-js | Pure-TS admin SDK, no React dependency, Node.js tools |
| mero-react | TypeScript/React | mero-react | React apps, hooks-based admin UI |
| calimero-client-js | TypeScript/JavaScript | calimero-client-js | Web apps, browser extensions, full auth flows |
Use Cases
Section titled “Use Cases”Sidecar Tools
Section titled “Sidecar Tools”Tools that run alongside Calimero nodes to provide additional functionality:
- Metrics collectors - Export node metrics to Prometheus, DataDog, etc.
- Log aggregators - Process and forward node logs
- Health checkers - Monitor node health and alert on issues
- Backup services - Periodically backup node state
- Monitoring dashboards - Custom dashboards for node status
Developer Tools
Section titled “Developer Tools”Utilities for development and testing:
- Test scripts - Automated testing of Calimero applications
- Deployment tools - Scripts for deploying and managing applications
- Debugging tools - Utilities for inspecting node state
- Development helpers - Scaffolding and code generation tools
Automation & CI/CD
Section titled “Automation & CI/CD”Automated workflows for DevOps:
- CI pipelines - Automated testing and deployment
- Release automation - Scripts for packaging and releasing
- Health monitoring - Automated health checks and alerts
- Data migration - Scripts for migrating data between nodes
mero-js SDK
Section titled “mero-js SDK”@calimero-network/mero-js (v2.x) is the primary pure-TypeScript admin SDK for Calimero. It has no React dependency and works in Node.js, browsers, and any framework. mero-react wraps it with React hooks.
Features
Section titled “Features”- No framework dependency — plain TypeScript, works anywhere
- Full admin API — namespaces, groups, members, contexts, metadata, capabilities
- Capability helpers — bitmask constants mirroring core’s
MemberCapabilities - SSE & WebSocket — real-time event subscriptions
- Cloud client — enable/disable HA
Installation
Section titled “Installation”npm install @calimero-network/mero-js# orpnpm add @calimero-network/mero-jsQuick Start
Section titled “Quick Start”import { createMeroJs } from '@calimero-network/mero-js';
const mero = createMeroJs({ nodeUrl: 'http://localhost:2528', accessToken: 'YOUR_JWT',});
// List namespacesconst namespaces = await mero.admin.listNamespaces();
// List subgroups of a groupconst subs = await mero.admin.listSubgroups('GROUP_ID');Capability Constants
Section titled “Capability Constants”The SDK exports CAPABILITIES — a bitmask constant object matching core’s MemberCapabilities — plus three helper functions:
import { CAPABILITIES, hasCap, withCap, withoutCap,} from '@calimero-network/mero-js';
// Check if a member has a specific capabilityconst canInvite = hasCap(member.capabilities, CAPABILITIES.CAN_INVITE_MEMBERS);const canManage = hasCap(member.capabilities, CAPABILITIES.MANAGE_MEMBERS);
// Build a bitmaskconst mask = withCap(0, CAPABILITIES.CAN_INVITE_MEMBERS);const restricted = withoutCap(mask, CAPABILITIES.CAN_CREATE_SUBGROUP);Available capability bits:
| Constant | Bit | Description |
|---|---|---|
CAN_CREATE_CONTEXT | 0 | Create contexts within a group |
CAN_INVITE_MEMBERS | 1 | Invite new members |
CAN_JOIN_OPEN_SUBGROUPS | 2 | Self-join open subgroups |
MANAGE_MEMBERS | 3 | Add/remove members |
MANAGE_APPLICATION | 4 | Change the group application |
CAN_CREATE_SUBGROUP | 5 | Create child groups |
CAN_DELETE_SUBGROUP | 6 | Delete child groups |
CAN_MANAGE_VISIBILITY | 7 | Set subgroup visibility |
CAN_MANAGE_METADATA | 8 | Write metadata records |
Note: Bits 9+ are unassigned — do not use them for application data; a future core release may claim them.
Admin API — New Methods (v2.x)
Section titled “Admin API — New Methods (v2.x)”joinSubgroupInheritance(groupId)
Section titled “joinSubgroupInheritance(groupId)”Materialises inherited membership in an open subgroup. Returns whether the call had to publish a MemberJoinedOpen op (wasInherited: true) or the caller was already a direct member (wasInherited: false).
const result = await mero.admin.joinSubgroupInheritance('GROUP_ID');console.log(result.wasInherited); // true | falseMetadata Records
Section titled “Metadata Records”Generic key/value metadata records for groups, members, and contexts:
// Group metadataawait mero.admin.setGroupMetadata('GROUP_ID', { name: 'Lobby', data: { color: 'blue' } });const groupMeta = await mero.admin.getGroupMetadata('GROUP_ID');
// Member metadataawait mero.admin.setMemberMetadata('GROUP_ID', 'MEMBER_ID', { name: 'Alice' });const memberMeta = await mero.admin.getMemberMetadata('GROUP_ID', 'MEMBER_ID');
// Context metadataawait mero.admin.setContextMetadata('GROUP_ID', 'CONTEXT_ID', { data: { key: 'value' } });const ctxMeta = await mero.admin.getContextMetadata('GROUP_ID', 'CONTEXT_ID');Subgroup Visibility
Section titled “Subgroup Visibility”const visibility = await mero.admin.getSubgroupVisibility('GROUP_ID');// Returns: 'open' | 'closed' | 'private'Breaking change (v2.0): The enum
DefaultVisibilitywas renamed toSubgroupVisibilityto match core. Update any code that importsDefaultVisibility.
Related Documentation
Section titled “Related Documentation”- Repository:
calimero-network/mero-js - NPM:
@calimero-network/mero-js
mero-react SDK
Section titled “mero-react SDK”@calimero-network/mero-react (v2.x) wraps mero-js with React hooks. Use it for React/Next.js applications that need admin UI.
Installation
Section titled “Installation”pnpm add @calimero-network/mero-react @calimero-network/mero-jsAvailable Hooks
Section titled “Available Hooks”All hooks follow the pattern: { result, loading, error, action } where result is the data and action is the async function to call.
Group management:
import { useNamespaceGroups, useSubgroups, useGroupInfo, useGroupMetadata, useSetGroupMetadata, useSetSubgroupVisibility, useSubgroupVisibility, useUpdateGroupSettings, useDeleteGroup, useNestGroup, useUnnestGroup, useCreateGroupInNamespace,} from '@calimero-network/mero-react';Member management:
import { useGroupMembers, useMemberMetadata, useSetMemberMetadata, useSetDefaultCapabilities, useDefaultCapabilities, useJoinSubgroupInheritance, useGroupInvitations,} from '@calimero-network/mero-react';Namespace & context management:
import { useNamespace, useNamespaceGroups, useCreateNamespace, useCreateNamespaceInvitation, useJoinNamespace, useDeleteNamespace, useSetContextMetadata, useDeleteContext, useJoinContext, useJoinGroup,} from '@calimero-network/mero-react';Example — join via subgroup inheritance:
import { useJoinSubgroupInheritance } from '@calimero-network/mero-react';
function JoinButton({ groupId }: { groupId: string }) { const { joinSubgroupInheritance, loading, error } = useJoinSubgroupInheritance();
const handleJoin = async () => { const result = await joinSubgroupInheritance(groupId); if (result?.wasInherited) { console.log('Joined via inheritance'); } };
return <button onClick={handleJoin} disabled={loading}>Join</button>;}Example — group metadata:
import { useGroupMetadata, useSetGroupMetadata } from '@calimero-network/mero-react';
function GroupEditor({ groupId }: { groupId: string }) { const { metadata, loading } = useGroupMetadata(groupId); const { setGroupMetadata } = useSetGroupMetadata();
return ( <div> <p>Name: {metadata?.name}</p> <button onClick={() => setGroupMetadata(groupId, { name: 'New Name' })}> Rename </button> </div> );}Breaking changes (v2.0):
useSetGroupAliasanduseSetMemberAliasare removed — useuseSetGroupMetadataanduseSetMemberMetadatainstead.- All group creation/invitation APIs changed
aliasfield toname.- Invitation responses use
groupNameinstead ofgroupAlias.
Related Documentation
Section titled “Related Documentation”- Repository:
calimero-network/mero-react - NPM:
@calimero-network/mero-react
Rust Client SDK
Section titled “Rust Client SDK”The Rust client SDK (core/crates/client) provides a trait-based abstraction for interacting with Calimero nodes. It’s designed for building command-line tools, sidecar services, and developer utilities.
Features
Section titled “Features”- Trait-based design - Flexible authentication and storage backends
- Async/await support - Full async support with
tokio - Comprehensive API - Access to all Calimero admin endpoints
- Error handling - Robust error types and handling
- Type safety - Strongly typed with Rust’s type system
Installation
Section titled “Installation”Add to your Cargo.toml:
[dependencies]calimero-client = { path = "../core/crates/client" }# Or from crates.io using "cargo add calimero-client"# calimero-client = "0.9.0"Quick Start
Section titled “Quick Start”use calimero_client::{create_connection, create_client, AuthMode, ConnectionInfo};use calimero_client::traits::{ClientAuthenticator, ClientStorage};use url::Url;
#[tokio::main]async fn main() -> eyre::Result<()> { // Create connection let api_url = Url::parse("http://localhost:2528")?; let authenticator = CliAuthenticator::new(); let storage = FileStorage::new();
let connection = ConnectionInfo::new( api_url, Some("node1".to_string()), authenticator, storage, );
// Create client let client = Client::new(connection)?;
// List contexts let contexts = client.list_contexts().await?; println!("Found {} contexts", contexts.data.len());
// List applications let apps = client.list_applications().await?; println!("Found {} applications", apps.data.len());
Ok(())}Authentication
Section titled “Authentication”use calimero_client::{AuthMode, ConnectionInfo};
let connection = ConnectionInfo::new( api_url, Some("node1".to_string()), CliAuthenticator::new(), FileStorage::new(),);API Examples
Section titled “API Examples”Context Management
Section titled “Context Management”// List all contextslet contexts = client.list_contexts().await?;
// Get specific contextlet context = client.get_context(&context_id).await?;
// Create new contextlet create_request = CreateContextRequest { application_id: app_id, protocol: "near".to_string(), params: Some(json!({"network": "testnet"}).to_string()),};let new_context = client.create_context(create_request).await?;
// Delete contextclient.delete_context(&context_id).await?;Application Management
Section titled “Application Management”// List applicationslet apps = client.list_applications().await?;
// Get applicationlet app = client.get_application(&app_id).await?;
// Install development applicationlet install_request = InstallDevApplicationRequest { path: "/path/to/app.wasm".to_string(), metadata: None,};client.install_dev_application(install_request).await?;
// Uninstall applicationclient.uninstall_application(&app_id).await?;Function Execution
Section titled “Function Execution”use calimero_client::client::Client;
// Execute function via JSON-RPClet result = client.execute_function( &context_id, "set_value", r#"{"key": "test", "value": "hello"}"#, &executor_public_key,).await?;Blob Management
Section titled “Blob Management”// Upload bloblet data = b"Hello, Calimero!".to_vec();let blob_info = client.upload_blob(data, Some(&context_id)).await?;
// List blobslet blobs = client.list_blobs().await?;
// Get blob infolet info = client.get_blob_info(&blob_id).await?;
// Delete blobclient.delete_blob(&blob_id).await?;Architecture
Section titled “Architecture”The Rust client uses a trait-based design for flexibility:
pub trait ClientAuthenticator { async fn authenticate(&self, url: &Url) -> Result<JwtToken>; // ...}
pub trait ClientStorage { async fn load_tokens(&self, node_name: &str) -> Result<Option<JwtToken>>; async fn save_tokens(&self, node_name: &str, tokens: &JwtToken) -> Result<()>; // ...}
pub struct Client<A, S>where A: ClientAuthenticator, S: ClientStorage,{ connection: ConnectionInfo<A, S>,}This allows you to implement custom authenticators and storage backends for your specific use case.
Error Handling
Section titled “Error Handling”use calimero_client::errors::ClientError;
match client.list_contexts().await { Ok(response) => println!("Success: {:?}", response), Err(ClientError::Network { message }) => { eprintln!("Network error: {}", message); } Err(ClientError::Authentication { message }) => { eprintln!("Auth error: {}", message); } Err(e) => eprintln!("Error: {:?}", e),}Related Documentation
Section titled “Related Documentation”- Repository:
calimero-network/core/crates/client - Source code:
core/crates/client/src
Python Client SDK
Section titled “Python Client SDK”The Python client SDK (calimero-client-py) provides Python bindings built with PyO3 for high-performance integration with Calimero nodes. Perfect for automation scripts, monitoring tools, and developer utilities.
Features
Section titled “Features”- High performance - Built with Rust and PyO3 for optimal performance
- Comprehensive API - Full access to Calimero Network functionality
- Type safety - Strongly typed Python bindings
- Synchronous API - All methods are synchronous from Python’s perspective; the Tokio runtime is managed internally by the Rust bindings
- Easy installation - Simple
pip install
Installation
Section titled “Installation”$: pip install calimero-client-py> ...> Successfully installed calimero-client-py-0.6.18Quick Start
Section titled “Quick Start”from calimero_client_py import create_connection, create_client
# Create connectionconnection = create_connection( api_url="http://localhost:2528", node_name="node1",)
client = create_client(connection)
# All methods are synchronous — no await neededcontexts = client.list_contexts()print(f"✓ Found contexts: {contexts}")
applications = client.list_applications()print(f"✓ Found applications: {applications}")Authentication
Section titled “Authentication”For local development with merod the auth is disabled so you can write any value for JWT access and refresh tokens.
$: python main.py> Starting authentication...> Please authenticate at: http://localhost:2528/> Enter access token: <ANY_VALUE>> Enter refresh token (optional): <ANY_VALUE>>> ✓ Found contexts: {'data': {'contexts': [{'applicationId': ....> ...> ✓ Found applications: {'data': {'apps': [{'blob': {'bytecode': 'Ca2zM5hue4Te2EYQnKmigkN7WcQHzBCuLFVSJ7zQte58', ' ...> ...API Examples
Section titled “API Examples”Context Management
Section titled “Context Management”# List all contextscontexts = client.list_contexts()
# Get specific contextcontext = client.get_context(context_id)
# Create new contextcontext = client.create_context( application_id="<APP_ID>", protocol="near", params='{"network": "testnet"}')
# Delete contextclient.delete_context(context_id)Application Management
Section titled “Application Management”# List applicationsapps = client.list_applications()
# Get applicationapp = client.get_application(app_id)
# Install development applicationresponse = client.install_dev_application( path="absolute/path/to/app.wasm", metadata=None)
# Uninstall applicationclient.uninstall_application(app_id)Function Execution
Section titled “Function Execution”# Execute function via JSON-RPCresult = client.execute_function( context_id=context_id, method="set_value", args='{"key": "test", "value": "hello"}', executor_public_key=executor_public_key)Blob Management
Section titled “Blob Management”# Upload blobwith open("file.dat", "rb") as f: data = f.read()blob_info = client.upload_blob(data, context_id=context_id)
# List blobsblobs = client.list_blobs()
# Get blob infoinfo = client.get_blob_info(blob_id)
# Delete blobclient.delete_blob(blob_id)Group & Namespace Management
Section titled “Group & Namespace Management”# Namespacesnamespaces = client.list_namespaces()ns = client.get_namespace(namespace_id)client.create_namespace(application_id="<APP_ID>", upgrade_policy="manual", name="My Namespace")invitation = client.create_namespace_invitation(namespace_id, expires_in_secs=3600)client.join_namespace(namespace_id, invitation_json)client.delete_namespace(namespace_id)
# Groupssubgroups = client.list_subgroups(group_id)info = client.get_group_info(group_id)client.create_group_in_namespace(namespace_id, name="Sub Group")client.reparent_group(group_id, new_parent_id)client.delete_group(group_id)
# Membersmembers = client.list_group_members(group_id)client.add_group_members(group_id, '[{"memberPublicKey": "KEY", "role": "admin"}]')client.remove_group_members(group_id, '["MEMBER_ID"]')client.update_member_role(group_id, member_id, "admin")
# Capabilitiescaps = client.get_member_capabilities(group_id, member_id)client.set_member_capabilities(group_id, member_id, 7) # bitmaskclient.set_default_capabilities(group_id, 7)client.set_member_auto_follow(group_id, member_id, True)
# Visibility & subgroup joinclient.set_subgroup_visibility(group_id, "open") # "open" | "closed" | "private"client.join_subgroup_inheritance(group_id) # materialise inherited open-subgroup membership
# Leaveclient.leave_context(context_id)client.leave_group(group_id)client.leave_namespace(namespace_id)Metadata Records
Section titled “Metadata Records”Generic metadata records for groups, members, and contexts (v0.6.x+):
# Group metadataclient.set_group_metadata(group_id, '{"name": "Lobby", "data": {"color": "blue"}}')meta = client.get_group_metadata(group_id)
# Member metadataclient.set_member_metadata(group_id, member_id, '{"name": "Alice"}')meta = client.get_member_metadata(group_id, member_id)
# Context metadataclient.set_context_metadata(group_id, context_id, '{"data": {"key": "value"}}')meta = client.get_context_metadata(group_id, context_id)Migration
Section titled “Migration”Methods for managing namespace application migrations (v0.6.17+):
# Check cascade migration status across a namespace subtreestatus = client.get_cascade_status(namespace_id)
# Logically abort an in-flight migration (idempotent)client.abort_migration(namespace_id)
# Upgrade a group to a new application version, optionally cascadingclient.upgrade_group(group_id, application_id, cascade=True)Error Handling
Section titled “Error Handling”from calimero_client_py import ClientError
try: contexts = client.list_contexts()except ClientError as e: if e.error_type == "Network": print(f"Network error: {e.message}") elif e.error_type == "Authentication": print(f"Auth error: {e.message}") else: print(f"Error: {e.message}")Related Documentation
Section titled “Related Documentation”- Repository:
calimero-network/calimero-client-py - PyPI Package:
calimero-client-py - Changelog:
CHANGELOG.md
calimero-client-js (Legacy Web SDK)
Section titled “calimero-client-js (Legacy Web SDK)”@calimero-network/calimero-client (calimero-client-js) is the legacy web-focused SDK providing full authentication flows, UI components, and the apiClient singleton for browser apps. For new projects building admin tooling or Node.js scripts, consider using mero-js or mero-react above.
Features
Section titled “Features”- Full authentication - JWT token management, wallet-based auth, React components
- Real-time updates - WebSocket and SSE subscriptions
- TypeScript support - Full type definitions
- React components - Pre-built UI components for authentication
- Browser & Node.js - Works in both environments
- Package management - List and query package registry
- Group management - Full namespace/group/member admin via
apiClient.node()
Installation
Section titled “Installation”# npmnpm install @calimero-network/calimero-client
# yarnyarn add @calimero-network/calimero-client
# pnpmpnpm add @calimero-network/calimero-clientQuick Start
Section titled “Quick Start”Basic Setup
Section titled “Basic Setup”The rpcClient allows you to make RPC calls to your node:
// KV Store exampleimport { setAppEndpointKey, setApplicationId, rpcClient,} from "@calimero-network/calimero-client";
// Configure node URL and application IDsetAppEndpointKey('http://localhost:2528');setApplicationId('APP_ID');
const contextId = 'CONTEXT_ID';const executorPublicKey = 'PUBLIC_KEY';
// Args = { key: string, value: string }// Output = { result: string }const setResponse = await rpcClient.execute<Args, Output>( { contextId, method: 'set', argsJson: { key: 'test', value: 'test' }, executorPublicKey, }, { headers: { 'Content-Type': 'application/json' }, timeout: 10000 });
const getResponse = await rpcClient.execute<Args, Output>( { contextId, method: 'get', argsJson: { key: 'test' }, executorPublicKey, }, { headers: { 'Content-Type': 'application/json' }, timeout: 10000 });Authentication Flow
Section titled “Authentication Flow”import { AppMode, CalimeroProvider CalimeroConnectButton, useCalimero,} from "@calimero-network/calimero-client";
const APPLICATION_ID = "<APPLICATION_ID>";const APPLICATION_PAHT = "<APPLICATION_PATH>";
// Wrap application logic in CalimeroProvider// CalimeroConnectButton -> handles connection to node; JWT generation and callback// Logout -> handles state cleanup and kills the connection to the nodefunction App() { const { logout } = useCalimero(); return ( <CalimeroProvider clientApplicationId={APPLICATION_ID} mode={AppMode.MultiContext} applicationPath={APPLICATION_PATH} > <YourApp /> <CalimeroConnectButton /> <button onClick={() => logout()}>Logout</button> </CalimeroProvider> );}Authentication
Section titled “Authentication”The JavaScript client has full authentication support including:
- JWT token management - Automatic token storage and refresh
- Wallet-based authentication - Support for NEAR wallet
- React components - Pre-built UI components (
CalimeroConnectButton,SetupModal) - Manual token handling - Direct token management APIs
Complete Authentication Flow
Section titled “Complete Authentication Flow”import { Routes, Route, useNavigate } from "react-router-dom";import { AppMode, CalimeroProvider CalimeroConnectButton, useCalimero,} from "@calimero-network/calimero-client";
function AuthPage() { return <CalimeroConnectButton />;}
function HomePage() { const { logout } = useCalimero(); return ( <Wrapper> <App> <button onClick={() => logout()}>Logout</button> </Wrapper> )}
function App() { const { isAuthenticated } = useCalimero(); const navigate = useNavigate();
useEffect(() => { if (isAuthenticated) { navigate("/home"); } else { navigate("/auth"); } }, [isAuthenticated]);
return ( <CalimeroProvider clientApplicationId={APPLICATION_ID} mode={AppMode.MultiContext} applicationPath={APPLICATION_PATH} > <Routes> <Route path="/auth" element={<AuthPage />} /> <Route path="/home" element={<HomePage />} /> </Routes> </CalimeroProvider> );}Manual Token Usage
Section titled “Manual Token Usage”import { setAccessToken, getJWTObject, rpcClient} from '@calimero-network/calimero-client';
// Set your tokensetAccessToken('your-jwt-token-here');
// Get contextId and executorPublicKey from the tokenconst jwt = getJWTObject();const contextId = jwt?.context_id;const executorPublicKey = jwt?.executor_public_key;
// Use the clientconst response = await rpcClient.execute<Args, Output>( { contextId, method: 'get', argsJson: { key: 'test' }, executorPublicKey, }, { headers: { 'Content-Type': 'application/json' }, timeout: 10000 });API Examples
Section titled “API Examples”The WsSubscriptionsClient enables real-time updates through WebSocket connections:
WebSocket Subscriptions
Section titled “WebSocket Subscriptions”import { useCalimero, getContextId } from "@calimero-network/calimero-client";import { WsSubscriptionsClient } from '@calimero-network/calimero-client';
const { app } = useCalimero();
const eventCallback = useCallback(async (event: WebSocketEvent) => { eventListenersRef.current.forEach((event: WebSocketEvent) => { // handle event console.log(event); }); }, []);
const subscriptionsClient = new WsSubscriptionsClient( process.env.NEXT_PUBLIC_API_URL, '/ws');// Subscripe to context eventsapp.subscribeToEvents([getContextId()], eventCallback);// Unsubscribe from context eventsapp.unsubscribeFromEvents([getContextId()]);SSE Subscriptions
Section titled “SSE Subscriptions”The SseSubscriptionsClient provides an HTTP-based alternative for real-time updates using Server-Sent Events:
import { SseSubscriptionsClient } from '@calimero-network/calimero-client';
const sseClient = new SseSubscriptionsClient( // e.g. http://localhost:2528 "<NODE-URL>", '/sse');
// Connect to SSE endpointawait sseClient.connect();// Subscribe to specific contextsawait sseClient.subscribe(["<APPLICATION_ID>"]);
// Handle incoming eventssseClient.addCallback((event) => { console.log('Received SSE event:', event);});
// Unsubscribe from contextsawait sseClient.unsubscribe(["<APPLICATION_ID>"]);
// Clean upsseClient.disconnect();Admin API
Section titled “Admin API”The Admin API allows you to call node functionalities. These can be: fetch context, fetch applications, fetch identities, create context, install application, others…
// apiClient automatically checks login authentication status so it needs to be paired with// CalimeroProvider and CalimeroConnectButton from previous stepsimport { apiClient,} from "@calimero-network/calimero-client";
// Contextsconst contexts = await apiClient.node().getContexts();const context = await apiClient.node().getContext(contextId);await apiClient.node().createContext({ applicationId: "<APP_ID>", protocol: "near" });await apiClient.node().deleteContext(contextId);await apiClient.node().joinContext(contextId);
// Applicationsconst applications = await apiClient.node().getInstalledApplications();await apiClient.node().installApplication("<APPLICATION_URL_PATH>");await apiClient.node().uninstallApplication(appId);
// Package registryconst packages = await apiClient.node().listPackages();const versions = await apiClient.node().listPackageVersions("package-name");const latest = await apiClient.node().getLatestPackageVersion("package-name");
// Namespaces & Groupsconst namespaces = await apiClient.node().listNamespaces();const ns = await apiClient.node().getNamespace(namespaceId);await apiClient.node().createNamespace({ applicationId: "<APP_ID>", upgradePolicy: "manual" });const invitation = await apiClient.node().createNamespaceInvitation(namespaceId, { expiresInSecs: 3600 });await apiClient.node().joinNamespace(namespaceId, invitationJson);const groups = await apiClient.node().listNamespaceGroups(namespaceId);await apiClient.node().createGroupInNamespace(namespaceId, { name: "Sub Group" });const members = await apiClient.node().listGroupMembers(groupId);await apiClient.node().addGroupMembers(groupId, [{ memberPublicKey: "KEY", role: "admin" }]);await apiClient.node().removeGroupMembers(groupId, ["MEMBER_ID"]);
// Root/client keysconst rootKeys = await apiClient.admin().getRootKeys();const clientKeys = await apiClient.admin().getClientKeys();await apiClient.admin().revokeClientKey("<ROOT_KEY_ID>", "<CLIENT_ID>");Error Handling
Section titled “Error Handling”try { const response = await rpcClient().execute<Args, Output>(...); if (response.error) { // Handle RPC error console.error('RPC Error:', response.error.message); } else { // Process successful response console.log('Result:', response.result); }} catch (error) { // Handle network or other errors console.error('Request failed:', error);}Best Practices
Section titled “Best Practices”Token Management
- Use
CalimeroProvider and CalimeroConnectButtonfor login and automatic token refresh - Store sensitive information in environment variables
- Never expose tokens in client-side code
Connection Management
- Always clean up WebSocket connections when done
- Use unique connection IDs for multiple connections
- Implement reconnection logic for production
Error Handling
- Always check for errors in RPC responses
- Implement proper error boundaries in React
- Log errors appropriately for debugging
Related Documentation
Section titled “Related Documentation”- Repository:
calimero-network/calimero-client-js - NPM Package:
@calimero-network/calimero-client - README:
calimero-client-js/README.md
Comparison
Section titled “Comparison”| Feature | Rust Client | Python Client | mero-js | mero-react | calimero-client-js |
|---|---|---|---|---|---|
| Language | Rust | Python | TypeScript | TypeScript/React | TypeScript |
| Performance | High (native) | High (Rust bindings) | Good | Good | Good |
| Authentication | ✅ Full support | ✅ Full support | ✅ JWT | ✅ JWT | ✅ JWT + wallet |
| Async Support | ✅ Tokio | ✅ Sync (Tokio internal) | ✅ Native | ✅ Native | ✅ Native |
| Type Safety | ✅ Rust types | ✅ Python types | ✅ TypeScript | ✅ TypeScript | ✅ TypeScript |
| React Components | ❌ | ❌ | ❌ | ✅ | ✅ |
| Capability Helpers | ❌ | ❌ | ✅ | ✅ (via mero-js) | ❌ |
| Metadata API | ❌ | ✅ | ✅ | ✅ | ❌ |
| Migration API | ❌ | ✅ | ✅ | ✅ | ❌ |
| WebSocket / SSE | ✅ | ✅ | ✅ | ✅ | ✅ |
| Best For | CLI tools, sidecars | Scripts, automation, CI | Node.js tools, admin SDK | React admin UI | Web apps, auth flows |
Choosing the Right SDK
Section titled “Choosing the Right SDK”Choose Rust Client if:
- Building command-line tools or sidecar services
- Need maximum performance
- Already using Rust in your stack
Choose Python Client if:
- Building automation scripts, monitoring, or CI/CD pipelines
- Driving merobox workflows programmatically
- Need migration management (
get_cascade_status,abort_migration)
Choose mero-js if:
- Building TypeScript/Node.js tools without a framework
- Need capability helpers or metadata records
- Integrating with non-React frameworks
Choose mero-react if:
- Building React or Next.js admin UIs
- Want hooks for group, namespace, and member management
Choose calimero-client-js if:
- Building web applications with full auth flows
- Need
CalimeroConnectButtonor wallet-based login - Working with the existing
apiClientsingleton pattern
Related Topics
Section titled “Related Topics”- meroctl CLI - Command-line interface for Calimero
- Merobox - YAML workflow orchestration (uses calimero-client-py internally)
- Introduction - Understanding Calimero’s core concepts
- Contexts - Working with contexts
- Identity - Authentication and identity management