Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@ The main work (all changes without a GitHub username in brackets in the below li
## __WORK IN PROGRESS__
-->

## __WORK IN PROGRESS__

- @matter/node
- Deprecation: `ClientNodeInteraction.localStateFor()` is scheduled for removal in 0.19 together with the legacy controller API
- Removed: `StructManager.assertDirectReadAuthorized()` and the direct-read authorization it backed, unused since the legacy cluster API was dropped

- @matter/protocol
- Deprecation: The legacy `DecodedDataReport` / `Decoded{Attribute,Event}Report*` types and the `normalize*` / `normalizeAndDecode*` helpers now announce removal in 0.19 instead of 0.18
- Deprecation: The legacy `ClusterType` command request surface (`Invoke.LegacyCommandRequest`, `Specifier.ClusterTypeCommand`) and `SessionManager.owner` are scheduled for removal in 0.19

- @matter/types
- Deprecation: The `ClusterType()` factory compat layer (`RetiredClusterType`, `RetiredElements`, the TLV `element` reverse mapping) is scheduled for removal in 0.19
- Deprecation: The generated `Cluster`, `Complete` and `<Name>Cluster` aliases and the `ClusterType.WithCompat` `with()` shim are scheduled for removal in 0.19

- @project-chip/matter.js
- Deprecation: Every class, type and function of the legacy controller API is now marked deprecated and scheduled for removal in 0.19; use the `ServerNode.peers` / `ClientNode` API of `@matter/node` instead

## 0.17.7 (2026-07-27)

- @matter/general
Expand Down Expand Up @@ -305,7 +322,7 @@ The main work (all changes without a GitHub username in brackets in the below li
- Feature: New `TrustedAsTestCertificate` attestation finding lets `onAttestationFailure` decide whether to accept devices whose PAA is only in the trust store as a test certificate; previously these failed with `PaaNotTrusted`. Adds per-call `considerTestCertificates` and a separate `acceptTestCertificates` trust policy on `DclCertificateService`
- Feature: `OnAttestationFailure` callback may return a `string` (wraps the underlying error as `cause` of a new `CommissioningError`) or throw to propagate verbatim
- Adjustment: Default-accept policies (`onAttestationFailure === true`/`undefined`) now commission test-PAA-only devices that previously failed; upgrade the policy to keep rejecting
- Deprecation: Internally used `DecodedDataReport`, `DecodedAttributeReport{Value,Status,Entry}`, `DecodedEventReport{Value,Status,Entry}`, `DecodedEventData`, and the `normalize*` / `normalizeAndDecode*` helpers moved to `@project-chip/matter.js/cluster`. Scheduled for removal in 0.18
- Deprecation: Internally used `DecodedDataReport`, `DecodedAttributeReport{Value,Status,Entry}`, `DecodedEventReport{Value,Status,Entry}`, `DecodedEventData`, and the `normalize*` / `normalizeAndDecode*` helpers moved to `@project-chip/matter.js/cluster`. Scheduled for removal in 0.19
- Enhancement: `ReadResult.EventValue` exposes the four wire timestamp variants (`epochTimestamp`, `systemTimestamp`, `deltaEpochTimestamp`, `deltaSystemTimestamp`) alongside the existing collapsed `timestamp: number`
- Adjustment: `ReadResult.Chunk` may now be an async iterable (`InputChunk` is an async generator); consumers iterate chunk contents with `for await … of chunk`. Mainly internal
- Fix: Fixes message counter rollover logic
Expand Down
11 changes: 6 additions & 5 deletions docs/MIGRATION_GUIDE_08.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ cluster definitions and this has now been enhanced for all device types. Additio
implemented also needed to be adjusted and was enhanced with a very flexible way to choose the wanted cluster features.

This means that developers need to adjust their code to use the new classes and concepts introduced by this change. The
former API (pre 0.8, called "Legacy" for of now) is still 100% functional, but will be deprecated and removed in upcoming
releases and might not get cluster specific adjustments or new features if they are not part of the core library
functionality!
The Controller API is still the same as before, but will be also adjusted in the future to the new concepts where
applicable.
former Device building API (pre 0.8, called "Legacy") was deprecated in 0.8 and removed in 0.13, so this document is
only relevant when migrating code that still targets a matter.js version before 0.13.

The legacy Controller API (`CommissioningController`, `PairedNode` and the surrounding classes of the
`@project-chip/matter.js` package) is deprecated as well and scheduled for removal in 0.19. Migrate to the
`ServerNode.peers` / `ClientNode` controller API of `@matter/node`.

This document tries to give an overview how the commonly used components and classes from the legacy API need to be
adjusted for the new API. Please also check out the FAQ at the end of this document.
Expand Down
33 changes: 27 additions & 6 deletions packages/matter.js/src/CommissioningController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ function discoveryKey(
return JSON.stringify({ id: identifierData, caps: discoveryCapabilities });
}

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export async function runDiscoverCommissionableDevices(
node: ServerNode,
identifierData: CommissionableDeviceIdentifiers,
Expand Down Expand Up @@ -113,6 +116,9 @@ export async function runDiscoverCommissionableDevices(
}
}

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export function cancelDiscoverCommissionableDevices(
identifierData: CommissionableDeviceIdentifiers,
discoveryCapabilities: TypeFromPartialBitSchema<typeof DiscoveryCapabilitiesBitmap> | undefined,
Expand All @@ -125,6 +131,9 @@ export function cancelDiscoverCommissionableDevices(
// TODO decline using setRoot*Cluster
// TODO Decline cluster access after announced/paired

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export type ControllerEnvironmentOptions = {
/**
* Environment to register the node with on start()
Expand All @@ -139,6 +148,8 @@ export type ControllerEnvironmentOptions = {

/**
* Constructor options for the CommissioningController class
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export type CommissioningControllerOptions = CommissioningControllerNodeOptions & {
/**
Expand Down Expand Up @@ -238,6 +249,8 @@ export type CommissioningControllerOptions = CommissioningControllerNodeOptions
/**
* Configuration for performing discovery + commissioning in one step.
* Kept in the legacy matter.js package; new code uses {@link CommissioningDiscovery.Options} directly.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export interface DiscoveryAndCommissioningOptions extends CommissioningOptions {
/** Discovery related options. */
Expand Down Expand Up @@ -275,14 +288,22 @@ export interface DiscoveryAndCommissioningOptions extends CommissioningOptions {
};
}

/** Options needed to commission a new node */
/**
* Options needed to commission a new node
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export type NodeCommissioningOptions = CommissioningControllerNodeOptions & {
commissioning: Omit<DiscoveryAndCommissioningOptions, "fabric" | "discovery" | "passcode">;
discovery: DiscoveryAndCommissioningOptions["discovery"];
passcode: number;
};

/** Controller class to commission and connect multiple nodes into one fabric. */
/**
* Controller class to commission and connect multiple nodes into one fabric.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class CommissioningController {
#crypto: Crypto;
#started = false;
Expand Down Expand Up @@ -557,7 +578,7 @@ export class CommissioningController {
}
}

/** @deprecated Use PairedNode.disconnect() instead */
/** @deprecated Scheduled for removal in 0.19. Use PairedNode.disconnect() instead */
async disconnectNode(nodeId: NodeId, force = false) {
const node = this.#pairedNodeForNodeId(nodeId);
if (node === undefined && !force) {
Expand Down Expand Up @@ -592,7 +613,7 @@ export class CommissioningController {
* This call is not blocking and returns an initialized PairedNode instance. The connection or reconnection
* happens in the background. Please monitor the state of the node to see if the connection was successful.
*
* @deprecated Use getNode() instead and call PairedNode.connect() or PairedNode.disconnect() as needed.
* @deprecated Scheduled for removal in 0.19. Use getNode() instead and call PairedNode.connect() or PairedNode.disconnect() as needed.
*/
connectNode(nodeId: NodeId, connectOptions?: CommissioningControllerNodeOptions, allowUnknownNode = false) {
return this.#createPairedNode(nodeId, connectOptions, allowUnknownNode);
Expand Down Expand Up @@ -683,7 +704,7 @@ export class CommissioningController {
* Connects to all paired nodes.
* After connection the endpoint data of the device is analyzed and an object structure is created.
*
* @deprecated Use getCommissionedNodes() to get the list of nodes and getNode(nodeId) instead and call PairedNode.connect() or PairedNode.disconnect() as needed.
* @deprecated Scheduled for removal in 0.19. Use getCommissionedNodes() to get the list of nodes and getNode(nodeId) instead and call PairedNode.connect() or PairedNode.disconnect() as needed.
*/
async connect(connectOptions?: CommissioningControllerNodeOptions) {
const controller = this.#assertControllerIsStarted();
Expand Down Expand Up @@ -741,7 +762,7 @@ export class CommissioningController {

/**
* Returns the PairedNode instance for a given node id, if this node is connected.
* @deprecated Use getNode() instead
* @deprecated Scheduled for removal in 0.19. Use getNode() instead
*/
getPairedNode(nodeId: NodeId) {
return this.#pairedNodeForNodeId(nodeId);
Expand Down
5 changes: 5 additions & 0 deletions packages/matter.js/src/ControllerStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { ImplementationError, MaybePromise, StorageContext, StorageManager } fro

/**
* Non-volatile state management for a {@link ControllerNode}.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class ControllerStore implements ControllerStoreInterface {
#storageManager?: StorageManager;
Expand Down Expand Up @@ -75,6 +77,9 @@ export class ControllerStore implements ControllerStoreInterface {
}
}

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export abstract class ControllerStoreInterface {
abstract erase(): Promise<void>;
abstract close(): Promise<void>;
Expand Down
2 changes: 2 additions & 0 deletions packages/matter.js/src/LegacyControllerStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { ControllerStoreInterface } from "./ControllerStore.js";
* The default implementation for matter.js uses synchronous APIs for storage.
* However, this will change in the future, and other implementations may be
* backed by asynchronous storage. So the public API is asynchronous.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class LegacyControllerStore implements ControllerStoreInterface {
#rootStorage: StorageContext;
Expand Down
14 changes: 13 additions & 1 deletion packages/matter.js/src/MatterController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Important note: This file is part of the legacy matter-node (internal) API and should not be used anymore directly!
* Please use the new API classes!
* @deprecated
* @deprecated Scheduled for removal in 0.19.
*/

import { ClusterClient } from "#cluster/client/ClusterClient.js";
Expand Down Expand Up @@ -94,6 +94,9 @@ import {
import { BasicInformation } from "@matter/types/clusters/basic-information";
import { GeneralCommissioning } from "@matter/types/clusters/general-commissioning";

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export type CommissionedNodeDetails = {
operationalServerAddress?: OperationalAddress;
discoveryData?: DiscoveryData;
Expand All @@ -110,6 +113,9 @@ type CommissionedPeer = PeerDescriptor & { deviceData?: DeviceInformationData };
// Backward-compatible persistence record for nodes
type StoredOperationalPeer = [NodeId, CommissionedNodeDetails];

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export type PairedNodeDetails = {
nodeId: NodeId;
operationalAddress?: string;
Expand All @@ -121,6 +127,9 @@ export type PairedNodeDetails = {
};
};

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class MatterController {
public static async create(options: {
id: string;
Expand Down Expand Up @@ -888,6 +897,9 @@ export class MatterController {
}
}

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export namespace MatterController {
export interface ConnectOptions extends PeerConnectionOptions {
allowUnknownPeer?: boolean;
Expand Down
2 changes: 2 additions & 0 deletions packages/matter.js/src/PaseCommissioner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ type PaseCommissionerOptions = Omit<CommissioningControllerOptions, "environment
* This represents a lightweight commissioner that can be used to start the commissioning process to commission
* devices into an existing controller fabric. Once the initial commissioning process is completed, it uses a callback
* to all to complete the commissioning process.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class PaseCommissioner {
readonly #environment: Environment;
Expand Down
8 changes: 8 additions & 0 deletions packages/matter.js/src/cluster/client/AttributeClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { InteractionClient } from "./InteractionClient.js";

/**
* Factory function to create an AttributeClient for a given attribute.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export function createAttributeClient<T>(
attribute: ClusterType.Attribute<T>,
Expand All @@ -33,6 +35,8 @@ export function createAttributeClient<T>(

/**
* General class for AttributeClients
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class AttributeClient<T = any> {
readonly #isWritable: boolean;
Expand Down Expand Up @@ -198,11 +202,15 @@ export class AttributeClient<T = any> {

/**
* Special AttributeClient class to allow identifying attributes that are supported because reported by the Devices.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class SupportedAttributeClient<T> extends AttributeClient<T> {}

/**
* Special AttributeClient class to allow identifying attributes that are supported because reported by the Devices,
* but the contained attribute is unknown.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class UnknownSupportedAttributeClient extends SupportedAttributeClient<any> {}
12 changes: 12 additions & 0 deletions packages/matter.js/src/cluster/client/ClusterClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ import { InteractionClient } from "./InteractionClient.js";

const logger = Logger.get("ClusterClient");

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export function GroupClusterClient<const N extends ClusterType.Concrete>(
clusterDef: N,
interactionClient: InteractionClient,
globalAttributeValues?: Record<string, unknown>,
): ClusterClientObj<N["Typing"]>;

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export function GroupClusterClient(
clusterDef: ClusterType.Concrete,
interactionClient: InteractionClient,
Expand All @@ -46,13 +52,19 @@ export function GroupClusterClient(
return ClusterClient(clusterDef as any, undefined, interactionClient, globalAttributeValues) as any;
}

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export function ClusterClient<const N extends ClusterType.Concrete>(
clusterDef: N,
endpointId: EndpointNumber | undefined,
interactionClient: InteractionClient,
globalAttributeValues?: Record<string, unknown>,
): ClusterClientObj<N["Typing"]>;

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export function ClusterClient(
clusterDef: ClusterType.Concrete,
endpointId: EndpointNumber | undefined,
Expand Down
13 changes: 13 additions & 0 deletions packages/matter.js/src/cluster/client/ClusterClientTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import {
} from "@matter/types";
import { DecodedEventData } from "./DecodedDataReport.js";

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export interface AttributeClientObj<T = any> {
readonly id: AttributeId;
readonly attribute: ClusterType.Attribute<T>;
Expand All @@ -39,6 +42,9 @@ export interface AttributeClientObj<T = any> {
removeListener(listener: (newValue: T) => void): void;
}

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export interface EventClientObj<T> {
readonly id: EventId;
readonly event: ClusterType.Event<T>;
Expand All @@ -62,6 +68,8 @@ export interface EventClientObj<T> {

/**
* Command options shared by all client command invocations.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export interface ClientCommandOptions {
/** Send this command as a timed request also when not required. Default timeout are 10 seconds. */
Expand Down Expand Up @@ -175,6 +183,8 @@ type ClientCommandsRecord<C> = ClientCommands<C> & Record<string, (...args: any[

/**
* Strongly typed interface of a cluster client.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export type ClusterClientObj<N extends ClusterTyping = ClusterTyping> = {
id: ClusterId;
Expand Down Expand Up @@ -209,6 +219,9 @@ export type ClusterClientObj<N extends ClusterTyping = ClusterTyping> = {
ClientEventSubscribers<N["Events"]> &
ClientEventListeners<N["Events"]>;

/**
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export type ClusterClientObjInternal = ClusterClientObj & {
/**
* Trigger an attribute update. This is mainly used internally and not needed to be called by the user.
Expand Down
4 changes: 4 additions & 0 deletions packages/matter.js/src/cluster/client/EventClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { InteractionClient } from "./InteractionClient.js";

/**
* Factory function to create an EventClient for a given event.
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export function createEventClient<T>(
event: ClusterType.Event<T>,
Expand All @@ -24,6 +26,8 @@ export function createEventClient<T>(

/**
* General class for EventClients
*
* @deprecated Scheduled for removal in 0.19. Part of the legacy controller API superseded by `ClientNode` in `@matter/node`.
*/
export class EventClient<T = any> {
readonly #listeners = new Array<(event: DecodedEventData<T>) => void>();
Expand Down
Loading
Loading