@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 declare class MidnightDIDResolver {
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;AAgCF,qBAAa,mBAAmB;IAC9B,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;CAWxC"}
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":"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","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-rc1",
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-rc1",
39
- "@midnight-ntwrk/midnight-did-domain": "0.5.0-rc1"
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
  }