Skip to main content

Device Commissioning

Commission a Matter device into a fabric using a QR code or manual onboarding payload. This is the primary integration path for “Add device” in Matter-enabled RainMaker apps.

info

A configured Commission Adaptor is required.

note

userInstance is the logged-in ESPRMUser.


Quick start

const { groups } = await userInstance.getGroups({ fabricOnly: true });
const fabric = groups.find(
(g) => g.name === "My Smart Home Fabric"
) as ESPRMFabric;

await fabric.getFabricDetails();

const cleanup = await fabric.startCommissioning(
"<QR_CODE_OR_ONBOARDING_PAYLOAD>",
(progress) => {
console.log(progress.status, progress.description);
// ON_PROGRESS | SUCCESS | FAILED
},
);

// When the screen unmounts or user cancels:
// cleanup();

Expected outcome: On success, progress reports SUCCESS and the device appears on the fabric (and in RainMaker for rainmaker_matter nodes).

Prepare the fabric first

Load fabric CA details before starting commissioning:

const { groups } = await userInstance.getGroups({ fabricOnly: true });
const fabric = groups.find(
(g) => g.name === "My Smart Home Fabric"
) as ESPRMFabric;

await fabric.getFabricDetails();

Commissioning only works on a Matter fabric (ESPRMFabric, isMatter === true). If the user picked a normal RainMaker group that is not a fabric yet, convert it first:

const { groups } = await userInstance.getGroups({ withFabricDetails: true });

const regularGroup = groups.find(
(g) => g.name === "My Smart Home" && !g.isMatter
);

if (regularGroup) {
const fabric = await regularGroup.convertToFabric();
await fabric.getFabricDetails();
// Use `fabric` for startCommissioning
}

See Create and manage fabrics for the full workflow: get groups, convertToFabric, then getFabricDetails(). To create a new Matter home instead of upgrading a group, use createFabric.

Progress handling

The callback receives ESPCommissioningResponse:

StatusMeaning
ON_PROGRESSShow status text (description) in UI
SUCCESSCommissioning finished; refresh node/fabric lists
FAILEDShow error; allow retry

Call the returned cleanup function to remove native event listeners when leaving the commissioning screen.


Commissioning sequence

Some platforms may require a background-capable execution path so NoC issuance and confirmation can complete reliably even if the UI is paused.


Manual commissioning flow

Use when you need custom UI, logging, or partial retries.

1. Issue node NoC

After the device provides a CSR (from native layer):

const commissioningRequest = await fabric.issueNodeNoC({
csr: "<BASE64_CSR>",
deviceId: "<MATTER_DEVICE_ID>",
tags: ["room:living_room"],
metadata: {
deviceName: "Smart Light",
},
});

2. Confirm commissioning

RainMaker Matter device:

await commissioningRequest.confirmMatterNodeCommissioning({
nodeType: "rainmaker_matter",
status: "success",
rainmakerNodeId: "<RAINMAKER_NODE_ID>",
matterNodeId: "<MATTER_NODE_ID>",
challengeResponse: "<SIGNED_CHALLENGE>",
metadata: {
firmwareVersion: "1.0.0",
},
});

Pure Matter device:

await commissioningRequest.confirmMatterNodeCommissioning({
nodeType: "pure_matter",
status: "success",
matterNodeId: "<MATTER_NODE_ID>",
});

Advanced: platform behavior

PlatformCloud API calls during startCommissioning
iOSCommonly performed from the active JS runtime while the commissioning screen is open
AndroidOften requires a background-capable execution path for NoC issuance / confirm

Implement a background-safe path when shipping cross-platform apps, especially if commissioning can continue while the user switches apps.

For the full Android stack (ChipTool commissioning UI, BLE, CHIP, Headless JS, and ESPMatterModule), see Android native bridge. For iOS (MatterSupport, MTRDeviceController, main RN runtime), see iOS native bridge. Start with Native Bridge for shared concepts and the layer model.


Error handling

FailureTypical cause
Missing QR dataEmpty onboarding payload
Missing Commission AdaptormatterCommissioningAdaptor not passed to configure()
Missing CSRNative event not normalized to requestData.csr
Confirm failedWrong nodeType, missing challenge for RainMaker Matter
Fabric not preparedSkipped getFabricDetails() before commissioning
Group is not a fabricCall convertToFabric on a regular group, or createFabric

Inspect ESPRMMatterCommissioningError and validation error codes returned by the SDK.

On this page