Skip to content
Helpers

Load the SDK

Load the SDK for mainnet, replace any of its endpoints, and handle what it checks before it returns.

loadNimbusSdk is the first call your app makes. It reads the settings the SDK ships for mainnet, checks the browser, and loads the SDK's WebAssembly. Every other function takes the NimbusSdk it returns, directly or through a session.

Load it once per page. One SDK serves any number of sessions, and it holds no keys.

Load it

import {  } from "@umbra/nimbus-solana-web";

const  = await (
  { : "mainnet" },
  { : "/nimbus/" },
);

assetsBaseUrl is the directory your app serves the SDK's files from, ending with /. Serve the SDK's files shows how to put them there.

Loading asks no wallet for anything. It fetches only the SDK's WebAssembly. Nimbus's services are first reached when a session opens or a payment runs.

The mainnet preset

The SDK ships a preset for mainnet. It holds the programs, the tokens, every service endpoint and the proving keys, the large files each proof is built from. So your app passes only assetsBaseUrl.

These are the mainnet preset's endpoints, read from the SDK when this site was built:

Optionmainnet presetGateway
endpoints.rpchttps://api.mainnet-beta.solana.comNo
endpoints.indexerhttps://data.api-v2.umbraprivacy.comNo
endpoints.contexthttps://context.api-v2.umbraprivacy.comNo
endpoints.guardians1: https://gateway.api-v2.umbraprivacy.com/guardian-share-node-relay-12: https://gateway.api-v2.umbraprivacy.com/guardian-share-node-relay-23: https://gateway.api-v2.umbraprivacy.com/guardian-share-node-relay-3Yes
endpoints.screeners0: https://gateway.api-v2.umbraprivacy.com/screenerYes
endpoints.dataEndorsers0: https://gateway.api-v2.umbraprivacy.com/data-endorserYes
endpoints.feeEnclavehttps://gateway.api-v2.umbraprivacy.com/fee-enclaveYes
endpoints.relayerhttps://gateway.api-v2.umbraprivacy.com/relayerYes
endpoints.coordinatorhttps://gateway.api-v2.umbraprivacy.com/process-coordinatorYes
endpoints.primitivesWasmYour app supplies itNo
provingKeyshttps://assets.api-v2.umbraprivacy.com/zk/No

primitivesWasm comes from assetsBaseUrl, so you rarely pass it yourself.

Replace an endpoint

Pass endpoints to replace any of the preset's, one at a time. The rest keep their preset values. The most common case is your own Solana RPC:

import {  } from "@umbra/nimbus-solana-web";

const  = await (
  { : "mainnet" },
  {
    : "/nimbus/",
    : { : "https://rpc.example.com" },
  },
);

The example app does the same when its settings name an RPC.

Endpoints shows how to point the SDK at services you run yourself.

If you replace an endpoint the gateway fronts, your replacement receives the session's gateway token. Point it only at a host you trust.

What your app reads from it

Treat every field of the SDK as read-only. These are the ones an app usually reads:

FieldWhat it holds
clusterThe cluster you loaded, "mainnet".
deployment.chainThe chain wallets sign for, such as solana:mainnet.
mintsThe tokens the preset lists, with their decimals. See Tokens.
settings.endpointsEvery endpoint, after your replacements.
settings.gatewayEndpointsThe services the gateway fronts, each with its URL. The gateway token goes only to these.
settings.assetPinning"pinned" when the SDK checks its own files before running them, "unpinned" when it does not.

Refuse an unpinned build

A packed copy of the package, the kind a registry serves, is always pinned. A copy built from source can be unpinned, and then runs its files unchecked. Refuse to go on in production if you see it:

if (.. !== "pinned") {
  throw new ("This build runs the SDK's files unchecked.");
}

What it checks

Before it returns, loadNimbusSdk makes sure the SDK can run safely on this page. Each failed check throws a NimbusSdkError:

What it checksReason when it failsHow to fix it
Every endpoint and the proving keys are set, and assetsBaseUrl ends with /misconfiguredPass what the message names.
The browser has fetch, Web Crypto, IndexedDB, Web Locks, storage and WebAssemblyunsupported-browserAsk the user for a current browser.
The page is cross-origin isolatedunsupported-browserSend the two headers.
The WebAssembly file can be fetchedservice-unavailableCheck assetsBaseUrl and that the files are served.
The file's SHA-256 is the one the package pinsdependency-nonconformingServe the files that shipped with this copy of the package.
The WebAssembly gives the right answers to its known-answer self-testsdependency-nonconformingThe same.
The file is WebAssembly at allunreadableCheck that assetsBaseUrl names the right directory.
The browser opens the SDK's cache in IndexedDBunsupported-browserSome private windows refuse it.

The prover worker is checked the same way when the first proof starts. Its script, and each file it loads, must match the SHA-256 the package pins.

Turn each reason into a message your user can act on:

import {  } from "@umbra/nimbus-solana-web";

function (: unknown): string {
  if (!()) return "The private balance could not load.";
  switch (.) {
    case "unsupported-browser":
      return "This browser cannot run private payments. Try a current Chrome, Firefox or Safari.";
    case "service-unavailable":
      return "The app's files could not be fetched. Try again.";
    case "misconfigured":
    case "dependency-nonconforming":
    case "unreadable":
      return "This app is set up wrongly. Please tell its developers.";
    case "wallet-unsupported":
    case "unauthorized":
    case "recipient-unregistered":
    case "account-unregistered":
      return "The private balance could not load.";
  }
}

Log thrown.message as well. It names the endpoint, file or browser feature at fault.

Next

Last updated

On this page