Skip to content

Zero-config connect

The hardest part of talking to a decentralised network is the chicken-and-egg problem: you need to know where the network is before you can ask it anything. Hardcoding https://some-validator-ip:3000 is brittle — that server might be down, rotated, or never the one you should be talking to.

connectToCluster solves this. You give it a network name; it resolves the network’s entrypoint, asks which clusters are active, and picks one of them at random.

sequenceDiagram
  participant App as Your app
  participant SDK as SDK
  participant Seed as Canonical gateway (KNOWN_NETWORKS)
  participant Cluster as Chosen cluster gateway

  App->>SDK: connectToCluster({ network: 'testnet', ... })
  SDK->>SDK: resolveNetwork('testnet') → bootstrap seed list
  SDK->>Seed: GET /api/v3/discovery/clusters
  Seed-->>SDK: active cluster set (each with a gatewayUrl)
  SDK->>SDK: random-pick one active cluster
  SDK-->>App: BaasClient bound to that cluster's gateway
  App->>Cluster: baas.authenticate(...) when you need a session

This is the recommended zero-config entrypoint for smart-apps using the database, storage, functions, messaging, or agents.

  1. Connect by network name.

    import { BaasClient } from '@hsuite/smart-engines-sdk';
    const baas = await BaasClient.connectToCluster({
    network: 'testnet',
    appId: 'app_abc',
    });
    await baas.db.insert('users', { name: 'Alice' });
  2. Authenticate when you need a session. BaasClient.connectToCluster returns the client directly (it does not authenticate for you — call baas.authenticate(...) when you need an authenticated session; see Authentication).

It defaults pathPrefix to /host, because cluster discovery hands back the gateway URL and the gateway routes BaaS traffic under /host/*. If you point the SDK at a bare host that isn’t behind a gateway, override with pathPrefix: ''.

Option Type Notes
network 'testnet' | 'mainnet' | 'devnet' Resolves the canonical gateway entrypoint. Mutually exclusive with bootstrap.
bootstrap string[] Explicit seed URLs (private deployments). Mutually exclusive with network.
appId string Your app id (e.g. from a prior deployment.init())
appName string App display name (registration)
pathPrefix string Defaults to /host. Set '' to hit a bare host.
timeout number Request timeout in ms (default 30000)
allowInsecure boolean Plain HTTP for the URLs you supply (bootstrap seeds, mirror node) — local dev only. Never admits plaintext registry entries.
allowInsecureClusters boolean Accept a plaintext gatewayUrl returned by the registry — only for a registry you run locally. Never implied by allowInsecure.
trustAnchor { network, registryTopicId, mirrorNodeUrl?, onFailure?, expectedValidatorKeys } Optional on-chain HCS gate over the discovery response: every nodeId must be registered and each record must bind the advertised gatewayUrl. expectedValidatorKeys maps each nodeId to the Ed25519 public key (hex) that must have signed its registry record; an unsigned or wrongly signed record is rejected. onFailure defaults to 'reject' (a mirror error or an empty registry throws TrustAnchorError); 'passthrough' is a non-production opt-in that returns the seed’s list unverified. The testnet registry topic is 0.0.9143793.

Earlier SDK versions shipped a second, validator-direct profile (SmartEngineClient + connectToNetwork) for raw-tier operations — accounts, tokens, transfers, TSS, IPFS, transaction preparation against /api/v3/{transactions,tss,ipfs,tokens,...}. As of SDK 8.0 it is retired: that tier has no public origin — the public gateway does not route it, and the on-chain validator registry publishes only a gatewayUrl, never a validator API endpoint — so connectToNetwork could never reach a deployed network. BaasClient.connectToCluster (above) is now the only public entrypoint. Transfers move through the entity-scoped surface instead:

import { BaasClient } from '@hsuite/smart-engines-sdk';
const baas = await BaasClient.connectToCluster({ network: 'testnet', appId: 'app_abc' });
await baas.authenticate({ chain: 'xrpl', walletAddress: wallet.address, publicKey: wallet.publicKey, signFn: sign });
const result = await baas.entities.transfer('entity-1', {
chain: 'xrpl',
to: 'rDestination...',
amount: '1000000', // drops
});

See the 8.0 CHANGELOG entry for the full migration.

For private deployments, local clusters, or pinning your own seed order, pass bootstrap instead of network:

const baas = await BaasClient.connectToCluster({
bootstrap: ['https://gateway.my-private-net.example'],
appId: 'app_abc',
});

Passing both network and bootstrap is a compile-time TypeScript error — the config is a discriminated union, so the type system stops the “which one wins?” ambiguity before runtime.

The SDK ships canonical entrypoints in KNOWN_NETWORKS:

Network Bootstrap entrypoint
testnet Live https://gateway.testnet.hsuite.network
mainnet https://gateway.hsuite.network Reserved
devnet https://gateway.develop.hsuite.network Reserved

The testnet is live on HSuite-operated validators. It opens to developers once the security audit is complete.

“Reserved” means the name resolves and type-checks today, but the network is not deployed for public use: discovery against it fails at runtime with the ordinary “no cluster reachable” error rather than a compile-time “unknown network” surprise. Mainnet has no date.

For testnet the SDK also ships the validator-registry anchor (the registry topic and each validator’s signing key) used to verify post-quantum attestations.

Customers who run their own validators should not extend this map — pass bootstrap: [...] directly instead.

networkFromEnv(explicit, env) resolves a NetworkName the same way the CLI does: an explicit value you already have wins outright, otherwise env.HSUITE_NETWORK is used if it names a known network, otherwise testnet.

import { networkFromEnv } from '@hsuite/smart-engines-sdk';
const baas = await BaasClient.connectToCluster({
network: networkFromEnv(undefined, process.env), // reads $HSUITE_NETWORK, else 'testnet'
appId: 'app_abc',
});
Condition Thrown
No cluster reachable via any seed 503
Neither a known network nor a non-empty bootstrap list 400
A seed returned only plaintext gateways InsecureClusterRegistryError
trustAnchor set (with onFailure: 'reject') and the registry can’t be read or is empty TrustAnchorError