Production checklist
What to check before real users arrive, and how to check each one.
Work through these before you ship. Each one says what to set up and how to check it in the deployed app.
Every page is cross-origin isolated
Both headers are on every route that loads the SDK, in production as well as in development. Turn on cross-origin isolation has the config for each host.
How to check. Open the deployed app and run crossOriginIsolated in the console. It must print
true. A CDN or proxy in front of your app can drop the headers, so check the live site.
The SDK's files are pinned and current
Your install runs nimbus-solana-web copy-assets, so the served files match the installed SDK.
Your app refuses to run a build that does not check its files:
if (.. !== "pinned") {
throw new ("Refusing to run unchecked WebAssembly.");
}How to check. sdk.settings.assetPinning reads "pinned" in the deployed app. A payment
then runs without a dependency-nonconforming error.
The Content Security Policy allows the SDK
A strict policy is your best defence for the user's signature, which the default store keeps readable by any script on your site. On top of your own rules, the SDK needs these:
script-src 'self' 'wasm-unsafe-eval';
worker-src 'self';
connect-src 'self' <every origin the SDK fetches from>;'wasm-unsafe-eval'lets the page and the workers compile WebAssembly. It does not allow JavaScripteval.worker-src 'self'lets the SDK start its workers. The prover worker and the threads it starts are scripts on your own site, soblob:is not needed.connect-srclists every origin the SDK fetches from. Build it from the loaded SDK, so it follows the preset and your own endpoints:
const { , } = .;
const = [
.,
.,
.,
.,
.,
.,
.....(() => .),
.....(() => .),
.....(() => .),
.,
].(() => !== "");
const = new (.(() => new (, .).));
.([...].(" "));Send the policy with the SDK's files too. A worker follows the policy its own script was served with, not the page's.
How to check. Run a deposit and a withdrawal with the console open. No policy violation is reported.
The files are cached sensibly
The SDK's files keep the same names from one version to the next. Serve them with a short cache
lifetime. Or copy them into a folder named for the version, such as /nimbus-0.1.0/, and cache that
for as long as you like.
The SDK caches the larger circuit files itself, in IndexedDB. They need nothing from you.
How to check. Upgrade the SDK, deploy, and load the app in a browser that visited before. It
loads without a dependency-nonconforming error.
The gateway token stays out of sight
Your app needs a gateway token for mainnet. To get one, email dev@umbraprivacy.com or reach out to any Umbra team member.
The SDK never logs the token or puts it in an error. Keep your own code the same:
- Keep the token out of your repository. Load it from your configuration at build or run time. The mainnet gateway token shows how to pass it.
- Never log request headers, or the options you pass to
openNimbusSession.
How to check. Search your logs and your error reports for the token. It appears nowhere.
You chose where the sign-in is kept
The signature that unlocks a private account can be kept for the tab, for the browser, or not at all. The first two are readable by any script on your site. Pick one on purpose, and tell your users. Sessions compares them.
How to check. Find the signatureSecretStore you pass to openNimbusSession. Leaving it out
means the tab store.
Errors reach your reports
Report what helps you fix a problem, and nothing secret:
- For a
NimbusSdkError, report itsreasonandmessage. The message never holds the token. - For a protocol refusal,
isNimbusSolanaFlowErrortells you it is one. Report itsreason. - For a result that is not a success, report its
kind. - Never report the session object. It holds the user's keys.
How to check. Load the app on a page without the isolation headers. Your reports show
unsupported-browser and the message.
Balances update while the app is open
Payments sync the device on their own. Payments others make to your user arrive only with a sync. Run one on an interval while a session is open, as Use it with React shows.
How to check. Leave the app open, and pay its user from another account. The balance updates without a reload.
Users can release stuck funds
A payment that stops halfway, because its tab closed or a step failed, keeps its funds reserved. A
sync frees one that never sent anything. Give users a button that calls releaseReservedNotes for
the rest.
Reserved funds shows the list and the button.
How to check. While listReservedSpends lists a payment, press the button. Its amount moves
from reserved back to available once nothing of it can still land.
You tested the browsers you support
The SDK's own tests run in headless Chrome only. Test your app in every browser you support, including on phones if you support them. Browser support lists what each browser must offer.
How to check. Run a deposit, a Private Send and a withdrawal in each browser.
Next
Last updated