SDK Pairing

A program pairs the same way an operator does: a short code from actana pair new, a fingerprint compared before the code is sent, a CSR signed by the Core. pairWithCore from @actana/sdk does the whole exchange.

npm install @actana/sdk
import { pairWithCore } from "@actana/sdk/core-pairing";

const blob = await pairWithCore({
  address: "core.example.com:8443",
  code: "XXXX-XXXX",
  sessionId,
  expectedCaFingerprint, // required — absent is not a skip
});

The client's private key is generated locally and never sent. The CA fingerprint is compared before the code is posted — expectedCaFingerprint is required, because absent is not waived. POST /v1/pair/redeem is the only pre-auth route on a Core.

Showing the fingerprint first

A UI that wants the operator to confirm the fingerprint before anything is spent uses fetchCorePairingIdentity: it dials with no code and returns the CA the Core presented, so you can render the fingerprint without leaking a secret you were never given. That is exactly what the Panel's Add a Core form and the CLI's interactive prompt do.

The registration blob

The resolved value is a registration blob: clientKey, PEMs, and the bearer. It is what a paired client holds, not what a human carries — treat it like a private key and never log it. Feed it to CoreClient.fromRegistrationBlob(blob) to open a core link.

import { CoreClient } from "@actana/sdk/core-client";

const client = CoreClient.fromRegistrationBlob(blob, { connectTimeoutMs: 15_000 });
await client.connect();

Refusals surface as typed failures matching the classes on Actana CLI Pairing — unreachable, fingerprint mismatch, hostname mismatch, refused, rate limited — the CLI is a thin skin over this same module.

See also

Built by Qcentic