@midnight-ntwrk/midnight-did 0.5.0-rc1 → 0.5.0-rc2
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/README.md
CHANGED
|
@@ -52,6 +52,15 @@ body is a DID Document byte stream. Midnight DID Document representations should
|
|
|
52
52
|
be reported as `application/did+ld+json` for JSON-LD streams or
|
|
53
53
|
`application/did+json` for DID Core JSON streams.
|
|
54
54
|
|
|
55
|
+
`MidnightDIDResolver.resolveRepresentation(did, { accept })` returns a
|
|
56
|
+
transport-neutral `Uint8Array | null` stream and DID Core resolution metadata.
|
|
57
|
+
The stream is null on resolution errors. The
|
|
58
|
+
default representation is `application/did+ld+json`; callers may request
|
|
59
|
+
`application/did+json`. Unsupported media types return
|
|
60
|
+
`representationNotSupported` without reading ledger state. A downstream HTTP
|
|
61
|
+
resolver should use this result for its response body and map only the result's
|
|
62
|
+
metadata/error to HTTP behavior.
|
|
63
|
+
|
|
55
64
|
## Identifier Canonicalization
|
|
56
65
|
|
|
57
66
|
```mermaid
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DIDContract } from "@midnight-ntwrk/midnight-did-contract";
|
|
2
|
-
import { type DIDDocumentMetadata, type DIDResolutionErrorCode } from "@midnight-ntwrk/midnight-did-domain";
|
|
2
|
+
import { type DIDDocumentMetadata, type DIDDocumentRepresentationMediaTypes, type DIDResolutionErrorCode } from "@midnight-ntwrk/midnight-did-domain";
|
|
3
3
|
import { MidnightNetwork } from "./midnight.js";
|
|
4
4
|
import { type MidnightDIDDocument } from "./midnight-did-document.js";
|
|
5
5
|
export type MidnightLedgerState = DIDContract.Ledger;
|
|
@@ -19,12 +19,32 @@ export type MidnightDIDResolutionResult = {
|
|
|
19
19
|
error?: DIDResolutionErrorCode;
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
|
-
export
|
|
22
|
+
export type MidnightDIDResolutionOptions = {
|
|
23
|
+
/** Requested DID Document representation media type(s). */
|
|
24
|
+
accept?: string | readonly string[];
|
|
25
|
+
};
|
|
26
|
+
export type MidnightDIDRepresentationResult = {
|
|
27
|
+
/** Null when resolution fails; otherwise the serialized DID Document. */
|
|
28
|
+
didDocumentStream: Uint8Array | null;
|
|
29
|
+
didDocumentMetadata: DIDDocumentMetadata;
|
|
30
|
+
didResolutionMetadata: {
|
|
31
|
+
contentType?: DIDDocumentRepresentationMediaTypes;
|
|
32
|
+
error?: DIDResolutionErrorCode;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export interface MidnightDIDResolverInterface {
|
|
36
|
+
resolve(did: string): Promise<MidnightDIDDocument>;
|
|
37
|
+
resolveResult(did: string): Promise<MidnightResolutionResult | null>;
|
|
38
|
+
resolveDIDResolutionResult(did: string): Promise<MidnightDIDResolutionResult>;
|
|
39
|
+
resolveRepresentation(did: string, options?: MidnightDIDResolutionOptions): Promise<MidnightDIDRepresentationResult>;
|
|
40
|
+
}
|
|
41
|
+
export declare class MidnightDIDResolver implements MidnightDIDResolverInterface {
|
|
23
42
|
private readonly ledgerReader;
|
|
24
43
|
private readonly expectedNetwork;
|
|
25
44
|
constructor(options: MidnightDIDResolverOptions);
|
|
26
45
|
resolve(did: string): Promise<MidnightDIDDocument>;
|
|
27
46
|
resolveResult(did: string): Promise<MidnightResolutionResult | null>;
|
|
28
47
|
resolveDIDResolutionResult(did: string): Promise<MidnightDIDResolutionResult>;
|
|
48
|
+
resolveRepresentation(did: string, options?: MidnightDIDResolutionOptions): Promise<MidnightDIDRepresentationResult>;
|
|
29
49
|
}
|
|
30
50
|
//# sourceMappingURL=midnight-did-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midnight-did-resolver.d.ts","sourceRoot":"","sources":["../src/midnight-did-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAG5B,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,MAAM,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG,CACjC,eAAe,EAAE,MAAM,KACpB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;AAEzC,MAAM,MAAM,0BAA0B,GAAG;IACvC,YAAY,EAAE,oBAAoB,CAAC;IACnC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,EAAE,mBAAmB,CAAC;IACjC,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACxC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,qBAAqB,EAAE;QACrB,KAAK,CAAC,EAAE,sBAAsB,CAAC;KAChC,CAAC;CACH,CAAC;
|
|
1
|
+
{"version":3,"file":"midnight-did-resolver.d.ts","sourceRoot":"","sources":["../src/midnight-did-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,mCAAmC,EACxC,KAAK,sBAAsB,EAG5B,MAAM,qCAAqC,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,MAAM,MAAM,mBAAmB,GAAG,WAAW,CAAC,MAAM,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG,CACjC,eAAe,EAAE,MAAM,KACpB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAC;AAEzC,MAAM,MAAM,0BAA0B,GAAG;IACvC,YAAY,EAAE,oBAAoB,CAAC;IACnC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,WAAW,EAAE,mBAAmB,CAAC;IACjC,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,WAAW,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACxC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,qBAAqB,EAAE;QACrB,KAAK,CAAC,EAAE,sBAAsB,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,yEAAyE;IACzE,iBAAiB,EAAE,UAAU,GAAG,IAAI,CAAC;IACrC,mBAAmB,EAAE,mBAAmB,CAAC;IACzC,qBAAqB,EAAE;QACrB,WAAW,CAAC,EAAE,mCAAmC,CAAC;QAClD,KAAK,CAAC,EAAE,sBAAsB,CAAC;KAChC,CAAC;CACH,CAAC;AAEF,MAAM,WAAW,4BAA4B;IAC3C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACnD,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAAC;IACrE,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAC9E,qBAAqB,CACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,4BAA4B,GACrC,OAAO,CAAC,+BAA+B,CAAC,CAAC;CAC7C;AAwHD,qBAAa,mBAAoB,YAAW,4BAA4B;IACtE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAuB;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAyB;gBAE7C,OAAO,EAAE,0BAA0B;IAKzC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQlD,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IA8BpE,0BAA0B,CAC9B,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,2BAA2B,CAAC;IAYjC,qBAAqB,CACzB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,+BAA+B,CAAC;CAuB5C"}
|
|
@@ -20,6 +20,61 @@ const resolutionErrorCode = (error) => {
|
|
|
20
20
|
}
|
|
21
21
|
return "internalError";
|
|
22
22
|
};
|
|
23
|
+
const supportedRepresentationMediaTypes = ["application/did+ld+json", "application/did+json"];
|
|
24
|
+
const requestedMediaTypes = (accept) => {
|
|
25
|
+
if (accept === undefined)
|
|
26
|
+
return [];
|
|
27
|
+
const values = (typeof accept === "string" ? [accept] : [...accept]).flatMap((value) => value.split(","));
|
|
28
|
+
return values
|
|
29
|
+
.map((value) => {
|
|
30
|
+
const [mediaType, ...parameters] = value.split(";");
|
|
31
|
+
const quality = parameters.find((parameter) => /^\s*q\s*=/i.test(parameter));
|
|
32
|
+
const qualityValue = quality?.split("=", 2)[1]?.trim();
|
|
33
|
+
return {
|
|
34
|
+
mediaType: mediaType?.trim().toLowerCase() ?? "",
|
|
35
|
+
quality: qualityValue === undefined ? 1 : Number(qualityValue),
|
|
36
|
+
};
|
|
37
|
+
})
|
|
38
|
+
.filter(({ mediaType, quality }) => mediaType !== "" && quality > 0)
|
|
39
|
+
.sort((left, right) => right.quality - left.quality)
|
|
40
|
+
.map(({ mediaType }) => mediaType);
|
|
41
|
+
};
|
|
42
|
+
const selectRepresentationMediaType = (accept) => {
|
|
43
|
+
if (accept === undefined ||
|
|
44
|
+
(Array.isArray(accept) && accept.length === 0) ||
|
|
45
|
+
(typeof accept === "string" && accept.trim() === "")) {
|
|
46
|
+
return "application/did+ld+json";
|
|
47
|
+
}
|
|
48
|
+
const requested = requestedMediaTypes(accept);
|
|
49
|
+
if (requested.length === 0) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
for (const value of requested) {
|
|
53
|
+
if (value === "*/*")
|
|
54
|
+
return "application/did+ld+json";
|
|
55
|
+
if (supportedRepresentationMediaTypes.includes(value)) {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
};
|
|
61
|
+
const documentForRepresentation = (didDocument, contentType) => {
|
|
62
|
+
if (contentType !== "application/did+json")
|
|
63
|
+
return didDocument;
|
|
64
|
+
const didJsonDocument = { ...didDocument };
|
|
65
|
+
Reflect.deleteProperty(didJsonDocument, "@context");
|
|
66
|
+
return didJsonDocument;
|
|
67
|
+
};
|
|
68
|
+
const representationEnvelope = (result, contentType, error) => ({
|
|
69
|
+
didDocumentStream: result === null || result === undefined
|
|
70
|
+
? null
|
|
71
|
+
: new TextEncoder().encode(JSON.stringify(documentForRepresentation(result.didDocument, contentType))),
|
|
72
|
+
didDocumentMetadata: result?.didDocumentMetadata ?? {},
|
|
73
|
+
didResolutionMetadata: {
|
|
74
|
+
...(contentType === undefined ? {} : { contentType }),
|
|
75
|
+
...(error === undefined ? {} : { error }),
|
|
76
|
+
},
|
|
77
|
+
});
|
|
23
78
|
export class MidnightDIDResolver {
|
|
24
79
|
ledgerReader;
|
|
25
80
|
expectedNetwork;
|
|
@@ -61,5 +116,20 @@ export class MidnightDIDResolver {
|
|
|
61
116
|
return resolutionEnvelope(null, resolutionErrorCode(error));
|
|
62
117
|
}
|
|
63
118
|
}
|
|
119
|
+
async resolveRepresentation(did, options = {}) {
|
|
120
|
+
const contentType = selectRepresentationMediaType(options.accept);
|
|
121
|
+
if (contentType === null) {
|
|
122
|
+
return representationEnvelope(null, undefined, "representationNotSupported");
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const result = await this.resolveResult(did);
|
|
126
|
+
return result === null
|
|
127
|
+
? representationEnvelope(null, undefined, "notFound")
|
|
128
|
+
: representationEnvelope(result, contentType);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
return representationEnvelope(null, undefined, resolutionErrorCode(error));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
64
134
|
}
|
|
65
135
|
//# sourceMappingURL=midnight-did-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"midnight-did-resolver.js","sourceRoot":"","sources":["../src/midnight-did-resolver.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,qCAAqC,CAAC;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AA2BhD,MAAM,kBAAkB,GAAG,CACzB,MAAuC,EACvC,KAA8B,EACD,EAAE,CAAC,CAAC;IACjC,WAAW,EAAE,MAAM,EAAE,WAAW,IAAI,IAAI;IACxC,mBAAmB,EAAE,MAAM,EAAE,mBAAmB,IAAI,EAAE;IACtD,qBAAqB,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE;CAC5D,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,EAAE,CACtC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzD,MAAM,mBAAmB,GAAG,CAAC,KAAc,EAA0B,EAAE;IACrE,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACpC,IACE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC/B,OAAO,CAAC,QAAQ,CAAC,oCAAoC,CAAC;QACtD,OAAO,CAAC,QAAQ,CAAC,iCAAiC,CAAC,EACnD,CAAC;QACD,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IACE,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAC;QAC1C,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EACpC,CAAC;QACD,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,OAAO,mBAAmB;IACb,YAAY,CAAuB;IACnC,eAAe,CAAyB;IAEzD,YAAY,OAAmC;QAC7C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW;QACvB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;QAC3C,CAAC;QACD,OAAO,MAAM,CAAC,WAAW,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAAW;QAC7B,MAAM,MAAM,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QAEjD,IAAI,OAAO,KAAK,eAAe,CAAC,QAAQ,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CACb,6GAA6G,CAC9G,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;YACtE,MAAM,IAAI,KAAK,CACb,oCAAoC,OAAO,cAAc,IAAI,CAAC,eAAe,EAAE,CAChF,CAAC;QACJ,CAAC;QAED,MAAM,eAAe,GAAG,EAAqB,CAAC;QAC9C,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;QAC7D,IAAI,WAAW,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAEtC,OAAO;YACL,WAAW,EAAE,cAAc,CAAC,wBAAwB,CAClD,WAAW,EACX,OAAO,EACP,eAAe,CAChB;YACD,mBAAmB,EAAE,cAAc,CAAC,qBAAqB,CAAC,WAAW,CAAC;SACvE,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,0BAA0B,CAC9B,GAAW;QAEX,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YAC7C,OAAO,kBAAkB,CACvB,MAAM,EACN,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CACzC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,kBAAkB,CAAC,IAAI,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF","sourcesContent":["import { DIDContract } from \"@midnight-ntwrk/midnight-did-contract\";\nimport {\n type ContractAddress,\n type DIDDocumentMetadata,\n type DIDResolutionErrorCode,\n parseMidnightDID,\n parseMidnightDIDString,\n} from \"@midnight-ntwrk/midnight-did-domain\";\n\nimport { LedgerToDomain } from \"./ledger-to-domain.js\";\nimport { MidnightNetwork } from \"./midnight.js\";\nimport { type MidnightDIDDocument } from \"./midnight-did-document.js\";\n\nexport type MidnightLedgerState = DIDContract.Ledger;\n\nexport type MidnightLedgerReader = (\n contractAddress: string,\n) => Promise<MidnightLedgerState | null>;\n\nexport type MidnightDIDResolverOptions = {\n ledgerReader: MidnightLedgerReader;\n expectedNetwork?: MidnightNetwork;\n};\n\nexport type MidnightResolutionResult = {\n didDocument: MidnightDIDDocument;\n didDocumentMetadata: DIDDocumentMetadata;\n};\n\nexport type MidnightDIDResolutionResult = {\n didDocument: MidnightDIDDocument | null;\n didDocumentMetadata: DIDDocumentMetadata;\n didResolutionMetadata: {\n error?: DIDResolutionErrorCode;\n };\n};\n\nconst resolutionEnvelope = (\n result: MidnightResolutionResult | null,\n error?: DIDResolutionErrorCode,\n): MidnightDIDResolutionResult => ({\n didDocument: result?.didDocument ?? null,\n didDocumentMetadata: result?.didDocumentMetadata ?? {},\n didResolutionMetadata: error === undefined ? {} : { error },\n});\n\nconst errorMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error);\n\nconst resolutionErrorCode = (error: unknown): DIDResolutionErrorCode => {\n const message = errorMessage(error);\n if (\n message.includes(\"Invalid DID\") ||\n message.includes(\"Invalid method-specific identifier\") ||\n message.includes(\"id must be a valid Midnight DID\")\n ) {\n return \"invalidDid\";\n }\n if (\n message.includes(\"Offchain Midnight DIDs\") ||\n message.includes(\"Network mismatch\")\n ) {\n return \"methodNotSupported\";\n }\n return \"internalError\";\n};\n\nexport class MidnightDIDResolver {\n private readonly ledgerReader: MidnightLedgerReader;\n private readonly expectedNetwork: MidnightNetwork | null;\n\n constructor(options: MidnightDIDResolverOptions) {\n this.ledgerReader = options.ledgerReader;\n this.expectedNetwork = options.expectedNetwork ?? null;\n }\n\n async resolve(did: string): Promise<MidnightDIDDocument> {\n const result = await this.resolveResult(did);\n if (result === null) {\n throw new Error(`DID not found: ${did}`);\n }\n return result.didDocument;\n }\n\n async resolveResult(did: string): Promise<MidnightResolutionResult | null> {\n const parsed = parseMidnightDIDString(did);\n const { network, id } = parseMidnightDID(parsed);\n\n if (network === MidnightNetwork.Offchain) {\n throw new Error(\n \"Offchain Midnight DIDs must be resolved from their long-form encoded state, not through the ledger resolver\",\n );\n }\n\n if (this.expectedNetwork !== null && network !== this.expectedNetwork) {\n throw new Error(\n `Network mismatch: DID network is ${network}, expected ${this.expectedNetwork}`,\n );\n }\n\n const contractAddress = id as ContractAddress;\n const ledgerState = await this.ledgerReader(contractAddress);\n if (ledgerState === null) return null;\n\n return {\n didDocument: LedgerToDomain.ledgerStateToDIDDocument(\n ledgerState,\n network,\n contractAddress,\n ),\n didDocumentMetadata: LedgerToDomain.ledgerStateToMetadata(ledgerState),\n };\n }\n\n async resolveDIDResolutionResult(\n did: string,\n ): Promise<MidnightDIDResolutionResult> {\n try {\n const result = await this.resolveResult(did);\n return resolutionEnvelope(\n result,\n result === null ? \"notFound\" : undefined,\n );\n } catch (error) {\n return resolutionEnvelope(null, resolutionErrorCode(error));\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"midnight-did-resolver.js","sourceRoot":"","sources":["../src/midnight-did-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import { DIDContract } from \"@midnight-ntwrk/midnight-did-contract\";\nimport {\n type ContractAddress,\n type DIDDocumentMetadata,\n type DIDDocumentRepresentationMediaTypes,\n type DIDResolutionErrorCode,\n parseMidnightDID,\n parseMidnightDIDString,\n} from \"@midnight-ntwrk/midnight-did-domain\";\n\nimport { LedgerToDomain } from \"./ledger-to-domain.js\";\nimport { MidnightNetwork } from \"./midnight.js\";\nimport { type MidnightDIDDocument } from \"./midnight-did-document.js\";\n\nexport type MidnightLedgerState = DIDContract.Ledger;\n\nexport type MidnightLedgerReader = (\n contractAddress: string,\n) => Promise<MidnightLedgerState | null>;\n\nexport type MidnightDIDResolverOptions = {\n ledgerReader: MidnightLedgerReader;\n expectedNetwork?: MidnightNetwork;\n};\n\nexport type MidnightResolutionResult = {\n didDocument: MidnightDIDDocument;\n didDocumentMetadata: DIDDocumentMetadata;\n};\n\nexport type MidnightDIDResolutionResult = {\n didDocument: MidnightDIDDocument | null;\n didDocumentMetadata: DIDDocumentMetadata;\n didResolutionMetadata: {\n error?: DIDResolutionErrorCode;\n };\n};\n\nexport type MidnightDIDResolutionOptions = {\n /** Requested DID Document representation media type(s). */\n accept?: string | readonly string[];\n};\n\nexport type MidnightDIDRepresentationResult = {\n /** Null when resolution fails; otherwise the serialized DID Document. */\n didDocumentStream: Uint8Array | null;\n didDocumentMetadata: DIDDocumentMetadata;\n didResolutionMetadata: {\n contentType?: DIDDocumentRepresentationMediaTypes;\n error?: DIDResolutionErrorCode;\n };\n};\n\nexport interface MidnightDIDResolverInterface {\n resolve(did: string): Promise<MidnightDIDDocument>;\n resolveResult(did: string): Promise<MidnightResolutionResult | null>;\n resolveDIDResolutionResult(did: string): Promise<MidnightDIDResolutionResult>;\n resolveRepresentation(\n did: string,\n options?: MidnightDIDResolutionOptions,\n ): Promise<MidnightDIDRepresentationResult>;\n}\n\nconst resolutionEnvelope = (\n result: MidnightResolutionResult | null,\n error?: DIDResolutionErrorCode,\n): MidnightDIDResolutionResult => ({\n didDocument: result?.didDocument ?? null,\n didDocumentMetadata: result?.didDocumentMetadata ?? {},\n didResolutionMetadata: error === undefined ? {} : { error },\n});\n\nconst errorMessage = (error: unknown) =>\n error instanceof Error ? error.message : String(error);\n\nconst resolutionErrorCode = (error: unknown): DIDResolutionErrorCode => {\n const message = errorMessage(error);\n if (\n message.includes(\"Invalid DID\") ||\n message.includes(\"Invalid method-specific identifier\") ||\n message.includes(\"id must be a valid Midnight DID\")\n ) {\n return \"invalidDid\";\n }\n if (\n message.includes(\"Offchain Midnight DIDs\") ||\n message.includes(\"Network mismatch\")\n ) {\n return \"methodNotSupported\";\n }\n return \"internalError\";\n};\n\nconst supportedRepresentationMediaTypes: readonly DIDDocumentRepresentationMediaTypes[] =\n [\"application/did+ld+json\", \"application/did+json\"];\n\nconst requestedMediaTypes = (\n accept: MidnightDIDResolutionOptions[\"accept\"],\n): string[] => {\n if (accept === undefined) return [];\n const values = (typeof accept === \"string\" ? [accept] : [...accept]).flatMap(\n (value) => value.split(\",\"),\n );\n return values\n .map((value) => {\n const [mediaType, ...parameters] = value.split(\";\");\n const quality = parameters.find((parameter) =>\n /^\\s*q\\s*=/i.test(parameter),\n );\n const qualityValue = quality?.split(\"=\", 2)[1]?.trim();\n return {\n mediaType: mediaType?.trim().toLowerCase() ?? \"\",\n quality: qualityValue === undefined ? 1 : Number(qualityValue),\n };\n })\n .filter(({ mediaType, quality }) => mediaType !== \"\" && quality > 0)\n .sort((left, right) => right.quality - left.quality)\n .map(({ mediaType }) => mediaType);\n};\n\nconst selectRepresentationMediaType = (\n accept: MidnightDIDResolutionOptions[\"accept\"],\n): DIDDocumentRepresentationMediaTypes | null => {\n if (\n accept === undefined ||\n (Array.isArray(accept) && accept.length === 0) ||\n (typeof accept === \"string\" && accept.trim() === \"\")\n ) {\n return \"application/did+ld+json\";\n }\n\n const requested = requestedMediaTypes(accept);\n if (requested.length === 0) {\n return null;\n }\n\n for (const value of requested) {\n if (value === \"*/*\") return \"application/did+ld+json\";\n if (\n supportedRepresentationMediaTypes.includes(\n value as DIDDocumentRepresentationMediaTypes,\n )\n ) {\n return value as DIDDocumentRepresentationMediaTypes;\n }\n }\n\n return null;\n};\n\nconst documentForRepresentation = (\n didDocument: MidnightDIDDocument,\n contentType?: DIDDocumentRepresentationMediaTypes,\n): MidnightDIDDocument => {\n if (contentType !== \"application/did+json\") return didDocument;\n\n const didJsonDocument = { ...didDocument };\n Reflect.deleteProperty(didJsonDocument, \"@context\");\n return didJsonDocument;\n};\n\nconst representationEnvelope = (\n result: MidnightResolutionResult | null,\n contentType?: DIDDocumentRepresentationMediaTypes,\n error?: DIDResolutionErrorCode,\n): MidnightDIDRepresentationResult => ({\n didDocumentStream:\n result === null || result === undefined\n ? null\n : new TextEncoder().encode(\n JSON.stringify(\n documentForRepresentation(result.didDocument, contentType),\n ),\n ),\n didDocumentMetadata: result?.didDocumentMetadata ?? {},\n didResolutionMetadata: {\n ...(contentType === undefined ? {} : { contentType }),\n ...(error === undefined ? {} : { error }),\n },\n});\n\nexport class MidnightDIDResolver implements MidnightDIDResolverInterface {\n private readonly ledgerReader: MidnightLedgerReader;\n private readonly expectedNetwork: MidnightNetwork | null;\n\n constructor(options: MidnightDIDResolverOptions) {\n this.ledgerReader = options.ledgerReader;\n this.expectedNetwork = options.expectedNetwork ?? null;\n }\n\n async resolve(did: string): Promise<MidnightDIDDocument> {\n const result = await this.resolveResult(did);\n if (result === null) {\n throw new Error(`DID not found: ${did}`);\n }\n return result.didDocument;\n }\n\n async resolveResult(did: string): Promise<MidnightResolutionResult | null> {\n const parsed = parseMidnightDIDString(did);\n const { network, id } = parseMidnightDID(parsed);\n\n if (network === MidnightNetwork.Offchain) {\n throw new Error(\n \"Offchain Midnight DIDs must be resolved from their long-form encoded state, not through the ledger resolver\",\n );\n }\n\n if (this.expectedNetwork !== null && network !== this.expectedNetwork) {\n throw new Error(\n `Network mismatch: DID network is ${network}, expected ${this.expectedNetwork}`,\n );\n }\n\n const contractAddress = id as ContractAddress;\n const ledgerState = await this.ledgerReader(contractAddress);\n if (ledgerState === null) return null;\n\n return {\n didDocument: LedgerToDomain.ledgerStateToDIDDocument(\n ledgerState,\n network,\n contractAddress,\n ),\n didDocumentMetadata: LedgerToDomain.ledgerStateToMetadata(ledgerState),\n };\n }\n\n async resolveDIDResolutionResult(\n did: string,\n ): Promise<MidnightDIDResolutionResult> {\n try {\n const result = await this.resolveResult(did);\n return resolutionEnvelope(\n result,\n result === null ? \"notFound\" : undefined,\n );\n } catch (error) {\n return resolutionEnvelope(null, resolutionErrorCode(error));\n }\n }\n\n async resolveRepresentation(\n did: string,\n options: MidnightDIDResolutionOptions = {},\n ): Promise<MidnightDIDRepresentationResult> {\n const contentType = selectRepresentationMediaType(options.accept);\n if (contentType === null) {\n return representationEnvelope(\n null,\n undefined,\n \"representationNotSupported\",\n );\n }\n\n try {\n const result = await this.resolveResult(did);\n return result === null\n ? representationEnvelope(null, undefined, \"notFound\")\n : representationEnvelope(result, contentType);\n } catch (error) {\n return representationEnvelope(\n null,\n undefined,\n resolutionErrorCode(error),\n );\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@midnight-ntwrk/midnight-did",
|
|
3
|
-
"version": "0.5.0-
|
|
3
|
+
"version": "0.5.0-rc2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"zod": "^4.1.0",
|
|
38
|
-
"@midnight-ntwrk/midnight-did-contract": "0.5.0-
|
|
39
|
-
"@midnight-ntwrk/midnight-did-domain": "0.5.0-
|
|
38
|
+
"@midnight-ntwrk/midnight-did-contract": "0.5.0-rc2",
|
|
39
|
+
"@midnight-ntwrk/midnight-did-domain": "0.5.0-rc2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"globals": "14.0.0"
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"precoverage": "pnpm --filter @midnight-ntwrk/midnight-did-domain build",
|
|
61
61
|
"coverage": "vitest run --coverage",
|
|
62
62
|
"clean": "rm -rf dist && rm -rf coverage",
|
|
63
|
-
"lint": "eslint src",
|
|
64
|
-
"lint:fix": "eslint src --fix"
|
|
63
|
+
"lint": "prettier --check \"src/**/*.{ts,tsx}\" && eslint src",
|
|
64
|
+
"lint:fix": "prettier --write \"src/**/*.{ts,tsx}\" && eslint src --fix"
|
|
65
65
|
}
|
|
66
66
|
}
|