@matter/protocol 0.15.0-alpha.0-20250619-df2264f15 → 0.15.0-alpha.0-20250624-e8c89f458
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/action/client/index.d.ts +1 -1
- package/dist/cjs/action/client/index.js +1 -1
- package/dist/cjs/action/errors.d.ts +12 -0
- package/dist/cjs/action/errors.d.ts.map +1 -1
- package/dist/cjs/action/errors.js +13 -1
- package/dist/cjs/action/errors.js.map +1 -1
- package/dist/cjs/action/protocols.d.ts +1 -1
- package/dist/cjs/action/protocols.js +1 -1
- package/dist/cjs/action/server/AttributeReadResponse.d.ts +1 -1
- package/dist/cjs/action/server/AttributeReadResponse.js +1 -1
- package/dist/cjs/action/server/AttributeSubscriptionResponse.d.ts +1 -1
- package/dist/cjs/action/server/AttributeSubscriptionResponse.js +1 -1
- package/dist/cjs/action/server/AttributeWriteResponse.d.ts +1 -1
- package/dist/cjs/action/server/AttributeWriteResponse.js +1 -1
- package/dist/cjs/action/server/CommandInvokeResponse.d.ts +1 -1
- package/dist/cjs/action/server/CommandInvokeResponse.js +1 -1
- package/dist/cjs/action/server/DataResponse.d.ts +1 -1
- package/dist/cjs/action/server/DataResponse.js +1 -1
- package/dist/cjs/action/server/EventReadResponse.d.ts +1 -1
- package/dist/cjs/action/server/EventReadResponse.js +1 -1
- package/dist/cjs/action/server/ServerInteraction.d.ts +1 -1
- package/dist/cjs/action/server/ServerInteraction.js +1 -1
- package/dist/cjs/action/server/index.d.ts +1 -1
- package/dist/cjs/action/server/index.js +1 -1
- package/dist/cjs/certificate/kinds/X509Base.d.ts +1 -1
- package/dist/cjs/certificate/kinds/X509Base.d.ts.map +1 -1
- package/dist/cjs/certificate/kinds/X509Base.js +40 -14
- package/dist/cjs/certificate/kinds/X509Base.js.map +1 -1
- package/dist/cjs/dcl/DclClient.d.ts +26 -0
- package/dist/cjs/dcl/DclClient.d.ts.map +1 -0
- package/dist/cjs/dcl/DclClient.js +119 -0
- package/dist/cjs/dcl/DclClient.js.map +6 -0
- package/dist/cjs/dcl/DclRestApiTypes.d.ts +49 -0
- package/dist/cjs/dcl/DclRestApiTypes.d.ts.map +1 -0
- package/dist/cjs/dcl/DclRestApiTypes.js +22 -0
- package/dist/cjs/dcl/DclRestApiTypes.js.map +6 -0
- package/dist/cjs/dcl/index.d.ts +7 -0
- package/dist/cjs/dcl/index.d.ts.map +1 -0
- package/dist/cjs/dcl/index.js +24 -0
- package/dist/cjs/dcl/index.js.map +6 -0
- package/dist/cjs/fabric/TestFabric.d.ts +1 -1
- package/dist/cjs/fabric/TestFabric.js +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/action/client/index.d.ts +1 -1
- package/dist/esm/action/client/index.js +1 -1
- package/dist/esm/action/errors.d.ts +12 -0
- package/dist/esm/action/errors.d.ts.map +1 -1
- package/dist/esm/action/errors.js +13 -1
- package/dist/esm/action/errors.js.map +1 -1
- package/dist/esm/action/protocols.d.ts +1 -1
- package/dist/esm/action/protocols.js +1 -1
- package/dist/esm/action/server/AttributeReadResponse.d.ts +1 -1
- package/dist/esm/action/server/AttributeReadResponse.js +1 -1
- package/dist/esm/action/server/AttributeSubscriptionResponse.d.ts +1 -1
- package/dist/esm/action/server/AttributeSubscriptionResponse.js +1 -1
- package/dist/esm/action/server/AttributeWriteResponse.d.ts +1 -1
- package/dist/esm/action/server/AttributeWriteResponse.js +1 -1
- package/dist/esm/action/server/CommandInvokeResponse.d.ts +1 -1
- package/dist/esm/action/server/CommandInvokeResponse.js +1 -1
- package/dist/esm/action/server/DataResponse.d.ts +1 -1
- package/dist/esm/action/server/DataResponse.js +1 -1
- package/dist/esm/action/server/EventReadResponse.d.ts +1 -1
- package/dist/esm/action/server/EventReadResponse.js +1 -1
- package/dist/esm/action/server/ServerInteraction.d.ts +1 -1
- package/dist/esm/action/server/ServerInteraction.js +1 -1
- package/dist/esm/action/server/index.d.ts +1 -1
- package/dist/esm/action/server/index.js +1 -1
- package/dist/esm/certificate/kinds/X509Base.d.ts +1 -1
- package/dist/esm/certificate/kinds/X509Base.d.ts.map +1 -1
- package/dist/esm/certificate/kinds/X509Base.js +40 -14
- package/dist/esm/certificate/kinds/X509Base.js.map +1 -1
- package/dist/esm/dcl/DclClient.d.ts +26 -0
- package/dist/esm/dcl/DclClient.d.ts.map +1 -0
- package/dist/esm/dcl/DclClient.js +99 -0
- package/dist/esm/dcl/DclClient.js.map +6 -0
- package/dist/esm/dcl/DclRestApiTypes.d.ts +49 -0
- package/dist/esm/dcl/DclRestApiTypes.d.ts.map +1 -0
- package/dist/esm/dcl/DclRestApiTypes.js +6 -0
- package/dist/esm/dcl/DclRestApiTypes.js.map +6 -0
- package/dist/esm/dcl/index.d.ts +7 -0
- package/dist/esm/dcl/index.d.ts.map +1 -0
- package/dist/esm/dcl/index.js +7 -0
- package/dist/esm/dcl/index.js.map +6 -0
- package/dist/esm/fabric/TestFabric.d.ts +1 -1
- package/dist/esm/fabric/TestFabric.js +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/package.json +6 -6
- package/src/action/client/index.ts +1 -1
- package/src/action/errors.ts +19 -1
- package/src/action/protocols.ts +1 -1
- package/src/action/server/AttributeReadResponse.ts +1 -1
- package/src/action/server/AttributeSubscriptionResponse.ts +1 -1
- package/src/action/server/AttributeWriteResponse.ts +1 -1
- package/src/action/server/CommandInvokeResponse.ts +1 -1
- package/src/action/server/DataResponse.ts +1 -1
- package/src/action/server/EventReadResponse.ts +1 -1
- package/src/action/server/ServerInteraction.ts +1 -1
- package/src/action/server/index.ts +1 -1
- package/src/certificate/kinds/X509Base.ts +54 -18
- package/src/dcl/DclClient.ts +140 -0
- package/src/dcl/DclRestApiTypes.ts +55 -0
- package/src/dcl/index.ts +7 -0
- package/src/fabric/TestFabric.ts +1 -1
- package/src/index.ts +1 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { MatterError } from "#general";
|
|
7
|
+
const DCL_PRODUCTION_URL = "https://on.dcl.csa-iot.org";
|
|
8
|
+
const DCL_TEST_URL = "https://on.test-net.dcl.csa-iot.org";
|
|
9
|
+
class MatterDclError extends MatterError {
|
|
10
|
+
}
|
|
11
|
+
class MatterDclResponseError extends MatterDclError {
|
|
12
|
+
constructor(path, error) {
|
|
13
|
+
super(`Error fetching ${path} from DCL: ${error.code} - ${error.message}`);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
class DclClient {
|
|
17
|
+
constructor(production = true) {
|
|
18
|
+
this.production = production;
|
|
19
|
+
this.#baseUrl = this.production ? DCL_PRODUCTION_URL : DCL_TEST_URL;
|
|
20
|
+
}
|
|
21
|
+
#baseUrl;
|
|
22
|
+
async #fetchJson(path) {
|
|
23
|
+
const url = new URL(path, this.#baseUrl);
|
|
24
|
+
try {
|
|
25
|
+
const response = await fetch(url.toString(), {
|
|
26
|
+
method: "GET",
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json"
|
|
29
|
+
},
|
|
30
|
+
signal: AbortSignal.timeout(5e3)
|
|
31
|
+
// 5 seconds timeout
|
|
32
|
+
});
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
throw new MatterDclResponseError(path, await response.json());
|
|
35
|
+
}
|
|
36
|
+
return await response.json();
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (error instanceof MatterDclResponseError) {
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
throw new MatterDclResponseError(path, {
|
|
42
|
+
code: 500,
|
|
43
|
+
message: error instanceof Error ? error.message : "Unknown Error",
|
|
44
|
+
details: []
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async fetchRootCertificateList() {
|
|
49
|
+
const certList = await this.#fetchJson("/certificates/approved");
|
|
50
|
+
if (certList?.approvedRootCertificates?.schemaVersion !== 0) {
|
|
51
|
+
throw new MatterDclError(
|
|
52
|
+
`Unsupported DCL Root Certificate schema version: ${certList.approvedRootCertificates.schemaVersion}`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return certList.approvedRootCertificates.certs;
|
|
56
|
+
}
|
|
57
|
+
async fetchRootCertificateBySubject(subject) {
|
|
58
|
+
const path = `/certificates/${encodeURIComponent(subject.subject)}/${encodeURIComponent(subject.subjectKeyId)}`;
|
|
59
|
+
const response = await this.#fetchJson(path);
|
|
60
|
+
if (!response || !response.approvedRootCertificates || response.approvedRootCertificates.subject !== subject.subject || response.approvedRootCertificates.subjectKeyId !== subject.subjectKeyId || response.approvedRootCertificates.schemaVersion !== 0) {
|
|
61
|
+
throw new MatterDclError(
|
|
62
|
+
`Root certificate not found for subject: ${subject.subject}, subjectKeyId: ${subject.subjectKeyId}`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return response.approvedRootCertificates.certs;
|
|
66
|
+
}
|
|
67
|
+
async fetchModelByVidPid(vid, pid) {
|
|
68
|
+
const path = `/models/model/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}`;
|
|
69
|
+
const response = await this.#fetchJson(path);
|
|
70
|
+
if (!response || !response.model || response.model.vid !== vid || response.model.pid !== pid || response.model.schemaVersion !== 0) {
|
|
71
|
+
throw new MatterDclError(`Model not found for VID: ${vid}, PID: ${pid}`);
|
|
72
|
+
}
|
|
73
|
+
return response.model;
|
|
74
|
+
}
|
|
75
|
+
async fetchModelVersionsByVidPid(vid, pid) {
|
|
76
|
+
const path = `/models/versions/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}`;
|
|
77
|
+
const response = await this.#fetchJson(path);
|
|
78
|
+
if (!response || !response.modelVersions || response.modelVersions.vid !== vid || response.modelVersions.pid !== pid || response.modelVersions.schemaVersion !== 0) {
|
|
79
|
+
throw new MatterDclError(`Model versions not found for VID: ${vid}, PID: ${pid}`);
|
|
80
|
+
}
|
|
81
|
+
return response.modelVersions.softwareVersions;
|
|
82
|
+
}
|
|
83
|
+
async fetchModelVersionByVidPidSoftwareVersion(vid, pid, softwareVersion) {
|
|
84
|
+
const path = `/models/versions/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}/${encodeURIComponent(softwareVersion)}`;
|
|
85
|
+
const response = await this.#fetchJson(path);
|
|
86
|
+
if (!response || !response.modelVersion || response.modelVersion.vid !== vid || response.modelVersion.pid !== pid || response.modelVersion.softwareVersion !== softwareVersion || response.modelVersion.schemaVersion !== 0) {
|
|
87
|
+
throw new MatterDclError(
|
|
88
|
+
`Model version not found for VID: ${vid}, PID: ${pid}, Software Version: ${softwareVersion}`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
return response.modelVersion;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
DclClient,
|
|
96
|
+
MatterDclError,
|
|
97
|
+
MatterDclResponseError
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=DclClient.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/dcl/DclClient.ts"],
|
|
4
|
+
"mappings": "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",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { DeviceModelDclSchema, DeviceSoftwareVersionModelDclSchema, ProductAttestationDclSchema } from "@matter/types";
|
|
7
|
+
export interface DclApiErrorResponse {
|
|
8
|
+
code: number;
|
|
9
|
+
message: string;
|
|
10
|
+
details: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface DclPkiRootCertificateSubjectReference {
|
|
13
|
+
subject: string;
|
|
14
|
+
subjectKeyId: string;
|
|
15
|
+
}
|
|
16
|
+
/** Response for /dcl/pki/certificates/approved */
|
|
17
|
+
export interface DclPkiRootCertificatesResponse {
|
|
18
|
+
approvedRootCertificates: {
|
|
19
|
+
certs: DclPkiRootCertificateSubjectReference[];
|
|
20
|
+
schemaVersion: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** Response for /dcl/pki/certificates/{subject}/{subjectKeyId} */
|
|
24
|
+
export interface DclPkiCertificateResponse {
|
|
25
|
+
approvedRootCertificates: {
|
|
26
|
+
subject: string;
|
|
27
|
+
subjectKeyId: string;
|
|
28
|
+
certs: ProductAttestationDclSchema[];
|
|
29
|
+
schemaVersion: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** Response for /dcl/models/model/{vid}/{pid} */
|
|
33
|
+
export interface DclModelModelsWithVidPidResponse {
|
|
34
|
+
model: DeviceModelDclSchema;
|
|
35
|
+
}
|
|
36
|
+
/** Response for /dcl/model/versions/{vid}/{pid} */
|
|
37
|
+
export interface DclModelVersionsWithVidPidResponse {
|
|
38
|
+
modelVersions: {
|
|
39
|
+
vid: number;
|
|
40
|
+
pid: number;
|
|
41
|
+
softwareVersions: number[];
|
|
42
|
+
schemaVersion: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Response for /dcl/model/versions/{vid}/{pid}/{softwareVersion} */
|
|
46
|
+
export interface DclModelVersionWithVidPidSoftwareVersionResponse {
|
|
47
|
+
modelVersion: DeviceSoftwareVersionModelDclSchema;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=DclRestApiTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DclRestApiTypes.d.ts","sourceRoot":"","sources":["../../../src/dcl/DclRestApiTypes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,oBAAoB,EAAE,mCAAmC,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAEvH,MAAM,WAAW,mBAAmB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,qCAAqC;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,kDAAkD;AAClD,MAAM,WAAW,8BAA8B;IAC3C,wBAAwB,EAAE;QACtB,KAAK,EAAE,qCAAqC,EAAE,CAAC;QAC/C,aAAa,EAAE,MAAM,CAAC;KACzB,CAAC;CACL;AAED,kEAAkE;AAClE,MAAM,WAAW,yBAAyB;IACtC,wBAAwB,EAAE;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,2BAA2B,EAAE,CAAC;QACrC,aAAa,EAAE,MAAM,CAAC;KACzB,CAAC;CACL;AAED,iDAAiD;AACjD,MAAM,WAAW,gCAAgC;IAC7C,KAAK,EAAE,oBAAoB,CAAC;CAC/B;AAED,mDAAmD;AACnD,MAAM,WAAW,kCAAkC;IAC/C,aAAa,EAAE;QACX,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,aAAa,EAAE,MAAM,CAAC;KACzB,CAAC;CACL;AAED,qEAAqE;AACrE,MAAM,WAAW,gDAAgD;IAC7D,YAAY,EAAE,mCAAmC,CAAC;CACrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dcl/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,gBAAgB,CAAC"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./certificate/index.js";
|
|
|
9
9
|
export * from "./cluster/index.js";
|
|
10
10
|
export * from "./codec/index.js";
|
|
11
11
|
export * from "./common/index.js";
|
|
12
|
+
export * from "./dcl/index.js";
|
|
12
13
|
export * from "./events/index.js";
|
|
13
14
|
export * from "./fabric/index.js";
|
|
14
15
|
export * from "./groups/index.js";
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC"}
|
package/dist/esm/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export * from "./certificate/index.js";
|
|
|
9
9
|
export * from "./cluster/index.js";
|
|
10
10
|
export * from "./codec/index.js";
|
|
11
11
|
export * from "./common/index.js";
|
|
12
|
+
export * from "./dcl/index.js";
|
|
12
13
|
export * from "./events/index.js";
|
|
13
14
|
export * from "./fabric/index.js";
|
|
14
15
|
export * from "./groups/index.js";
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
4
|
+
"mappings": "AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matter/protocol",
|
|
3
|
-
"version": "0.15.0-alpha.0-
|
|
3
|
+
"version": "0.15.0-alpha.0-20250624-e8c89f458",
|
|
4
4
|
"description": "Low-level APIs for Matter interaction",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"iot",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"#*": "./src/*"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@matter/general": "0.15.0-alpha.0-
|
|
44
|
-
"@matter/model": "0.15.0-alpha.0-
|
|
45
|
-
"@matter/types": "0.15.0-alpha.0-
|
|
43
|
+
"@matter/general": "0.15.0-alpha.0-20250624-e8c89f458",
|
|
44
|
+
"@matter/model": "0.15.0-alpha.0-20250624-e8c89f458",
|
|
45
|
+
"@matter/types": "0.15.0-alpha.0-20250624-e8c89f458"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@matter/tools": "0.15.0-alpha.0-
|
|
49
|
-
"@matter/testing": "0.15.0-alpha.0-
|
|
48
|
+
"@matter/tools": "0.15.0-alpha.0-20250624-e8c89f458",
|
|
49
|
+
"@matter/testing": "0.15.0-alpha.0-20250624-e8c89f458"
|
|
50
50
|
},
|
|
51
51
|
"files": [
|
|
52
52
|
"dist/**/*",
|
package/src/action/errors.ts
CHANGED
|
@@ -80,6 +80,15 @@ export class ConstraintError extends ValidateError {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Thrown when an enum value is not known based on Matter specification
|
|
85
|
+
*/
|
|
86
|
+
export class UnknownEnumValueError extends ValidateError {
|
|
87
|
+
constructor(path: SchemaErrorPath, message: string) {
|
|
88
|
+
super(path, message, StatusCode.ConstraintError);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
83
92
|
/**
|
|
84
93
|
* Thrown when conformance is violated.
|
|
85
94
|
*/
|
|
@@ -91,7 +100,16 @@ export class ConformanceError extends ValidateError {
|
|
|
91
100
|
} else {
|
|
92
101
|
prefix = `Conformance "${(schema as ValueModel).conformance}"`;
|
|
93
102
|
}
|
|
94
|
-
super(path, `${prefix}: ${message}`, StatusCode.
|
|
103
|
+
super(path, `${prefix}: ${message}`, StatusCode.ConstraintError);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Thrown when an enum value is not valid based on conformance definitions
|
|
109
|
+
*/
|
|
110
|
+
export class EnumValueConformanceError extends ConformanceError {
|
|
111
|
+
constructor(schema: Schema, path: SchemaErrorPath, message: string) {
|
|
112
|
+
super(schema, path, message);
|
|
95
113
|
}
|
|
96
114
|
}
|
|
97
115
|
|
package/src/action/protocols.ts
CHANGED
|
@@ -340,34 +340,70 @@ export abstract class X509Base<CT extends X509Certificate> {
|
|
|
340
340
|
/**
|
|
341
341
|
* Extract the public key from a Certificate Signing Request (CSR) in ASN.1 DER format.
|
|
342
342
|
*/
|
|
343
|
-
static async getPublicKeyFromCsr(crypto: Crypto,
|
|
344
|
-
const { [DerKey.Elements]: rootElements } = DerCodec.decode(
|
|
345
|
-
if (rootElements?.length !== 3)
|
|
343
|
+
static async getPublicKeyFromCsr(crypto: Crypto, encodedCsr: Uint8Array) {
|
|
344
|
+
const { [DerKey.Elements]: rootElements } = DerCodec.decode(encodedCsr);
|
|
345
|
+
if (rootElements?.length !== 3) {
|
|
346
|
+
throw new CertificateError("Invalid CSR data");
|
|
347
|
+
}
|
|
346
348
|
const [requestNode, signAlgorithmNode, signatureNode] = rootElements;
|
|
347
349
|
|
|
348
350
|
// Extract the public key
|
|
349
351
|
const { [DerKey.Elements]: requestElements } = requestNode;
|
|
350
|
-
if (requestElements?.length !== 4)
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
352
|
+
if (requestElements?.length !== 4) {
|
|
353
|
+
throw new CertificateError("Invalid CSR data");
|
|
354
|
+
}
|
|
355
|
+
const [versionNode, subjectNode, publicKeyNode] = requestElements;
|
|
356
|
+
const requestVersionBytes = versionNode[DerKey.Bytes];
|
|
357
|
+
if (requestVersionBytes.length !== 1 || requestVersionBytes[0] !== 0) {
|
|
358
|
+
throw new CertificateError(`Unsupported CSR version ${requestVersionBytes[0]}`);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Verify the subject, according to spec can be "any value", so just check that it exists
|
|
362
|
+
if (!subjectNode[DerKey.Elements]?.length) {
|
|
363
|
+
throw new CertificateError("Missing subject in CSR data");
|
|
364
|
+
}
|
|
355
365
|
|
|
356
366
|
const { [DerKey.Elements]: publicKeyElements } = publicKeyNode;
|
|
357
|
-
if (publicKeyElements?.length !== 2)
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
const
|
|
367
|
+
if (publicKeyElements?.length !== 2) {
|
|
368
|
+
throw new CertificateError("Invalid CSR data");
|
|
369
|
+
}
|
|
370
|
+
const [publicKeyTypeNode, publicKeyBytesNode] = publicKeyElements;
|
|
361
371
|
|
|
362
|
-
// Verify
|
|
372
|
+
// Verify Public Key Algorithm Type
|
|
373
|
+
const { [DerKey.Elements]: publicKeyTypeNodeElements } = publicKeyTypeNode;
|
|
374
|
+
if (publicKeyTypeNodeElements?.length !== 2) {
|
|
375
|
+
throw new CertificateError("Invalid public key type in CSR");
|
|
376
|
+
}
|
|
363
377
|
if (
|
|
364
|
-
signAlgorithmNode[DerKey.Elements]?.[0]?.[DerKey.Bytes] === undefined ||
|
|
365
378
|
!Bytes.areEqual(
|
|
366
|
-
|
|
367
|
-
|
|
379
|
+
publicKeyTypeNodeElements[0][DerKey.Bytes],
|
|
380
|
+
X962.PublicKeyAlgorithmEcPublicKey[DerKey.Bytes],
|
|
368
381
|
)
|
|
369
|
-
)
|
|
370
|
-
throw new CertificateError("Unsupported
|
|
382
|
+
) {
|
|
383
|
+
throw new CertificateError("Unsupported public key algorithm in CSR");
|
|
384
|
+
}
|
|
385
|
+
// Verify Public Key Curve Type (Parameter to Algorithm)
|
|
386
|
+
if (
|
|
387
|
+
!Bytes.areEqual(
|
|
388
|
+
publicKeyTypeNodeElements[1][DerKey.Bytes],
|
|
389
|
+
X962.PublicKeyAlgorithmEcPublicKeyP256[DerKey.Bytes],
|
|
390
|
+
)
|
|
391
|
+
) {
|
|
392
|
+
throw new CertificateError("Unsupported public key curve in CSR");
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const publicKey = publicKeyBytesNode[DerKey.Bytes];
|
|
396
|
+
|
|
397
|
+
// Verify the CSR signature algorithm
|
|
398
|
+
const signatureAlgorithmBytes = signAlgorithmNode[DerKey.Elements]?.[0]?.[DerKey.Bytes];
|
|
399
|
+
if (
|
|
400
|
+
signatureAlgorithmBytes === undefined ||
|
|
401
|
+
!Bytes.areEqual(X962.EcdsaWithSHA256[DerKey.ObjectId][DerKey.Bytes], signatureAlgorithmBytes)
|
|
402
|
+
) {
|
|
403
|
+
throw new CertificateError("Unsupported signature algorithm in CSR");
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Verify the CSR signature
|
|
371
407
|
await crypto.verifyEcdsa(
|
|
372
408
|
PublicKey(publicKey),
|
|
373
409
|
DerCodec.encode(requestNode),
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022-2025 Matter.js Authors
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import {
|
|
7
|
+
DclApiErrorResponse,
|
|
8
|
+
DclModelModelsWithVidPidResponse,
|
|
9
|
+
DclModelVersionsWithVidPidResponse,
|
|
10
|
+
DclModelVersionWithVidPidSoftwareVersionResponse,
|
|
11
|
+
DclPkiCertificateResponse,
|
|
12
|
+
DclPkiRootCertificatesResponse,
|
|
13
|
+
DclPkiRootCertificateSubjectReference,
|
|
14
|
+
} from "#dcl/DclRestApiTypes.js";
|
|
15
|
+
import { MatterError } from "#general";
|
|
16
|
+
|
|
17
|
+
const DCL_PRODUCTION_URL = "https://on.dcl.csa-iot.org";
|
|
18
|
+
const DCL_TEST_URL = "https://on.test-net.dcl.csa-iot.org";
|
|
19
|
+
|
|
20
|
+
/** Base class for all DCL-related errors */
|
|
21
|
+
export class MatterDclError extends MatterError {}
|
|
22
|
+
|
|
23
|
+
/** Error thrown when fetching data from DCL fails */
|
|
24
|
+
export class MatterDclResponseError extends MatterDclError {
|
|
25
|
+
constructor(path: string, error: DclApiErrorResponse) {
|
|
26
|
+
super(`Error fetching ${path} from DCL: ${error.code} - ${error.message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A client clas to use "fetch" to get REST DAta from DCL (Decentraland) */
|
|
31
|
+
export class DclClient {
|
|
32
|
+
#baseUrl: string;
|
|
33
|
+
|
|
34
|
+
constructor(private readonly production: boolean = true) {
|
|
35
|
+
this.#baseUrl = this.production ? DCL_PRODUCTION_URL : DCL_TEST_URL;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async #fetchJson<ResponseT>(path: string): Promise<ResponseT> {
|
|
39
|
+
const url = new URL(path, this.#baseUrl);
|
|
40
|
+
try {
|
|
41
|
+
const response = await fetch(url.toString(), {
|
|
42
|
+
method: "GET",
|
|
43
|
+
headers: {
|
|
44
|
+
"Content-Type": "application/json",
|
|
45
|
+
},
|
|
46
|
+
signal: AbortSignal.timeout(5_000), // 5 seconds timeout
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
if (!response.ok) {
|
|
50
|
+
throw new MatterDclResponseError(path, await response.json());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return await response.json();
|
|
54
|
+
} catch (error) {
|
|
55
|
+
if (error instanceof MatterDclResponseError) {
|
|
56
|
+
throw error; // Re-throw custom DCL error
|
|
57
|
+
}
|
|
58
|
+
throw new MatterDclResponseError(path, {
|
|
59
|
+
code: 500,
|
|
60
|
+
message: error instanceof Error ? error.message : "Unknown Error",
|
|
61
|
+
details: [],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async fetchRootCertificateList() {
|
|
67
|
+
const certList = await this.#fetchJson<DclPkiRootCertificatesResponse>("/certificates/approved");
|
|
68
|
+
if (certList?.approvedRootCertificates?.schemaVersion !== 0) {
|
|
69
|
+
throw new MatterDclError(
|
|
70
|
+
`Unsupported DCL Root Certificate schema version: ${certList.approvedRootCertificates.schemaVersion}`,
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return certList.approvedRootCertificates.certs;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async fetchRootCertificateBySubject(subject: DclPkiRootCertificateSubjectReference) {
|
|
77
|
+
const path = `/certificates/${encodeURIComponent(subject.subject)}/${encodeURIComponent(subject.subjectKeyId)}`;
|
|
78
|
+
const response = await this.#fetchJson<DclPkiCertificateResponse>(path);
|
|
79
|
+
if (
|
|
80
|
+
!response ||
|
|
81
|
+
!response.approvedRootCertificates ||
|
|
82
|
+
response.approvedRootCertificates.subject !== subject.subject ||
|
|
83
|
+
response.approvedRootCertificates.subjectKeyId !== subject.subjectKeyId ||
|
|
84
|
+
response.approvedRootCertificates.schemaVersion !== 0
|
|
85
|
+
) {
|
|
86
|
+
throw new MatterDclError(
|
|
87
|
+
`Root certificate not found for subject: ${subject.subject}, subjectKeyId: ${subject.subjectKeyId}`,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
return response.approvedRootCertificates.certs;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async fetchModelByVidPid(vid: number, pid: number) {
|
|
94
|
+
const path = `/models/model/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}`;
|
|
95
|
+
const response = await this.#fetchJson<DclModelModelsWithVidPidResponse>(path);
|
|
96
|
+
if (
|
|
97
|
+
!response ||
|
|
98
|
+
!response.model ||
|
|
99
|
+
response.model.vid !== vid ||
|
|
100
|
+
response.model.pid !== pid ||
|
|
101
|
+
response.model.schemaVersion !== 0
|
|
102
|
+
) {
|
|
103
|
+
throw new MatterDclError(`Model not found for VID: ${vid}, PID: ${pid}`);
|
|
104
|
+
}
|
|
105
|
+
return response.model;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async fetchModelVersionsByVidPid(vid: number, pid: number) {
|
|
109
|
+
const path = `/models/versions/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}`;
|
|
110
|
+
const response = await this.#fetchJson<DclModelVersionsWithVidPidResponse>(path);
|
|
111
|
+
if (
|
|
112
|
+
!response ||
|
|
113
|
+
!response.modelVersions ||
|
|
114
|
+
response.modelVersions.vid !== vid ||
|
|
115
|
+
response.modelVersions.pid !== pid ||
|
|
116
|
+
response.modelVersions.schemaVersion !== 0
|
|
117
|
+
) {
|
|
118
|
+
throw new MatterDclError(`Model versions not found for VID: ${vid}, PID: ${pid}`);
|
|
119
|
+
}
|
|
120
|
+
return response.modelVersions.softwareVersions;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async fetchModelVersionByVidPidSoftwareVersion(vid: number, pid: number, softwareVersion: number) {
|
|
124
|
+
const path = `/models/versions/${encodeURIComponent(vid)}/${encodeURIComponent(pid)}/${encodeURIComponent(softwareVersion)}`;
|
|
125
|
+
const response = await this.#fetchJson<DclModelVersionWithVidPidSoftwareVersionResponse>(path);
|
|
126
|
+
if (
|
|
127
|
+
!response ||
|
|
128
|
+
!response.modelVersion ||
|
|
129
|
+
response.modelVersion.vid !== vid ||
|
|
130
|
+
response.modelVersion.pid !== pid ||
|
|
131
|
+
response.modelVersion.softwareVersion !== softwareVersion ||
|
|
132
|
+
response.modelVersion.schemaVersion !== 0
|
|
133
|
+
) {
|
|
134
|
+
throw new MatterDclError(
|
|
135
|
+
`Model version not found for VID: ${vid}, PID: ${pid}, Software Version: ${softwareVersion}`,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
return response.modelVersion;
|
|
139
|
+
}
|
|
140
|
+
}
|