@oma3/omatrust 0.1.0-alpha.0
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/LICENSE +21 -0
- package/README.md +30 -0
- package/dist/app-registry/index.cjs +244 -0
- package/dist/app-registry/index.cjs.map +1 -0
- package/dist/app-registry/index.d.cts +1 -0
- package/dist/app-registry/index.d.ts +1 -0
- package/dist/app-registry/index.js +209 -0
- package/dist/app-registry/index.js.map +1 -0
- package/dist/identity/index.cjs +332 -0
- package/dist/identity/index.cjs.map +1 -0
- package/dist/identity/index.d.cts +1 -0
- package/dist/identity/index.d.ts +1 -0
- package/dist/identity/index.js +296 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/index-ChbJxwOA.d.cts +415 -0
- package/dist/index-ChbJxwOA.d.ts +415 -0
- package/dist/index-QZDExA4I.d.cts +90 -0
- package/dist/index-QZDExA4I.d.ts +90 -0
- package/dist/index-_Bkhoj8k.d.cts +93 -0
- package/dist/index-_Bkhoj8k.d.ts +93 -0
- package/dist/index.cjs +1838 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1824 -0
- package/dist/index.js.map +1 -0
- package/dist/reputation/index.cjs +1470 -0
- package/dist/reputation/index.cjs.map +1 -0
- package/dist/reputation/index.d.cts +1 -0
- package/dist/reputation/index.d.ts +1 -0
- package/dist/reputation/index.js +1416 -0
- package/dist/reputation/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { keccak256, toUtf8Bytes, getAddress, isAddress, sha256 } from 'ethers';
|
|
2
|
+
import canonicalize from 'canonicalize';
|
|
3
|
+
|
|
4
|
+
// src/identity/did.ts
|
|
5
|
+
|
|
6
|
+
// src/shared/errors.ts
|
|
7
|
+
var OmaTrustError = class extends Error {
|
|
8
|
+
code;
|
|
9
|
+
details;
|
|
10
|
+
constructor(code, message, details) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = "OmaTrustError";
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.details = details;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// src/shared/assert.ts
|
|
19
|
+
function assertString(value, name, code = "INVALID_INPUT") {
|
|
20
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
21
|
+
throw new OmaTrustError(code, `${name} must be a non-empty string`, { value });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/identity/caip.ts
|
|
26
|
+
var CAIP_10_REGEX = /^(?<namespace>[a-z0-9-]+):(?<reference>[a-zA-Z0-9-]+):(?<address>.+)$/;
|
|
27
|
+
var CAIP_2_REGEX = /^(?<namespace>[a-z0-9-]+):(?<reference>[a-zA-Z0-9-]+)$/;
|
|
28
|
+
function parseCaip10(input) {
|
|
29
|
+
assertString(input, "input", "INVALID_CAIP");
|
|
30
|
+
const trimmed = input.trim();
|
|
31
|
+
const match = trimmed.match(CAIP_10_REGEX);
|
|
32
|
+
if (!match?.groups) {
|
|
33
|
+
throw new OmaTrustError("INVALID_CAIP", "Invalid CAIP-10 format", { input });
|
|
34
|
+
}
|
|
35
|
+
const namespace = match.groups.namespace;
|
|
36
|
+
const reference = match.groups.reference;
|
|
37
|
+
const address = match.groups.address;
|
|
38
|
+
if (!namespace || !reference || !address) {
|
|
39
|
+
throw new OmaTrustError("INVALID_CAIP", "Invalid CAIP-10 components", { input });
|
|
40
|
+
}
|
|
41
|
+
return { namespace, reference, address };
|
|
42
|
+
}
|
|
43
|
+
function buildCaip10(namespace, reference, address) {
|
|
44
|
+
assertString(namespace, "namespace", "INVALID_CAIP");
|
|
45
|
+
assertString(reference, "reference", "INVALID_CAIP");
|
|
46
|
+
assertString(address, "address", "INVALID_CAIP");
|
|
47
|
+
return `${namespace}:${reference}:${address}`;
|
|
48
|
+
}
|
|
49
|
+
function normalizeCaip10(input) {
|
|
50
|
+
const parsed = parseCaip10(input);
|
|
51
|
+
const namespace = parsed.namespace.toLowerCase();
|
|
52
|
+
const reference = parsed.reference;
|
|
53
|
+
let address = parsed.address;
|
|
54
|
+
if (namespace === "eip155") {
|
|
55
|
+
address = address.toLowerCase();
|
|
56
|
+
}
|
|
57
|
+
return buildCaip10(namespace, reference, address);
|
|
58
|
+
}
|
|
59
|
+
function buildCaip2(namespace, reference) {
|
|
60
|
+
assertString(namespace, "namespace", "INVALID_CAIP");
|
|
61
|
+
assertString(reference, "reference", "INVALID_CAIP");
|
|
62
|
+
return `${namespace}:${reference}`;
|
|
63
|
+
}
|
|
64
|
+
function parseCaip2(caip2) {
|
|
65
|
+
assertString(caip2, "caip2", "INVALID_CAIP");
|
|
66
|
+
const trimmed = caip2.trim();
|
|
67
|
+
const match = trimmed.match(CAIP_2_REGEX);
|
|
68
|
+
if (!match?.groups) {
|
|
69
|
+
throw new OmaTrustError("INVALID_CAIP", "Invalid CAIP-2 format", { caip2 });
|
|
70
|
+
}
|
|
71
|
+
const namespace = match.groups.namespace;
|
|
72
|
+
const reference = match.groups.reference;
|
|
73
|
+
if (!namespace || !reference) {
|
|
74
|
+
throw new OmaTrustError("INVALID_CAIP", "Invalid CAIP-2 components", { caip2 });
|
|
75
|
+
}
|
|
76
|
+
return { namespace, reference };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/identity/did.ts
|
|
80
|
+
var DID_REGEX = /^did:[a-z0-9]+:.+$/i;
|
|
81
|
+
function isValidDid(did) {
|
|
82
|
+
return DID_REGEX.test(did);
|
|
83
|
+
}
|
|
84
|
+
function extractDidMethod(did) {
|
|
85
|
+
const match = did.match(/^did:([a-z0-9]+):/i);
|
|
86
|
+
return match ? match[1] : null;
|
|
87
|
+
}
|
|
88
|
+
function extractDidIdentifier(did) {
|
|
89
|
+
const match = did.match(/^did:[a-z0-9]+:(.+)$/i);
|
|
90
|
+
return match ? match[1] : null;
|
|
91
|
+
}
|
|
92
|
+
function normalizeDomain(domain) {
|
|
93
|
+
assertString(domain, "domain", "INVALID_DID");
|
|
94
|
+
return domain.trim().toLowerCase().replace(/\.$/, "");
|
|
95
|
+
}
|
|
96
|
+
function normalizeDidWeb(input) {
|
|
97
|
+
assertString(input, "input", "INVALID_DID");
|
|
98
|
+
const trimmed = input.trim();
|
|
99
|
+
if (trimmed.startsWith("did:") && !trimmed.startsWith("did:web:")) {
|
|
100
|
+
throw new OmaTrustError("INVALID_DID", "Expected did:web DID", { input });
|
|
101
|
+
}
|
|
102
|
+
const identifier = trimmed.startsWith("did:web:") ? trimmed.slice("did:web:".length) : trimmed;
|
|
103
|
+
const [host, ...pathParts] = identifier.split("/");
|
|
104
|
+
if (!host) {
|
|
105
|
+
throw new OmaTrustError("INVALID_DID", "Invalid did:web identifier", { input });
|
|
106
|
+
}
|
|
107
|
+
const normalizedHost = normalizeDomain(host);
|
|
108
|
+
const path = pathParts.length > 0 ? `/${pathParts.join("/")}` : "";
|
|
109
|
+
return `did:web:${normalizedHost}${path}`;
|
|
110
|
+
}
|
|
111
|
+
function normalizeDidPkh(input) {
|
|
112
|
+
assertString(input, "input", "INVALID_DID");
|
|
113
|
+
const trimmed = input.trim();
|
|
114
|
+
if (!trimmed.startsWith("did:pkh:")) {
|
|
115
|
+
throw new OmaTrustError("INVALID_DID", "Expected did:pkh DID", { input });
|
|
116
|
+
}
|
|
117
|
+
const parts = trimmed.split(":");
|
|
118
|
+
if (parts.length !== 5) {
|
|
119
|
+
throw new OmaTrustError("INVALID_DID", "Invalid did:pkh format", { input });
|
|
120
|
+
}
|
|
121
|
+
const [, , namespace, chainId, address] = parts;
|
|
122
|
+
if (!namespace || !chainId || !address) {
|
|
123
|
+
throw new OmaTrustError("INVALID_DID", "Invalid did:pkh components", { input });
|
|
124
|
+
}
|
|
125
|
+
return `did:pkh:${namespace.toLowerCase()}:${chainId}:${address.toLowerCase()}`;
|
|
126
|
+
}
|
|
127
|
+
function normalizeDidHandle(input) {
|
|
128
|
+
assertString(input, "input", "INVALID_DID");
|
|
129
|
+
const trimmed = input.trim();
|
|
130
|
+
if (!trimmed.startsWith("did:handle:")) {
|
|
131
|
+
throw new OmaTrustError("INVALID_DID", "Expected did:handle DID", { input });
|
|
132
|
+
}
|
|
133
|
+
const parts = trimmed.split(":");
|
|
134
|
+
if (parts.length !== 4) {
|
|
135
|
+
throw new OmaTrustError("INVALID_DID", "Invalid did:handle format", { input });
|
|
136
|
+
}
|
|
137
|
+
const [, , platform, username] = parts;
|
|
138
|
+
if (!platform || !username) {
|
|
139
|
+
throw new OmaTrustError("INVALID_DID", "Invalid did:handle components", { input });
|
|
140
|
+
}
|
|
141
|
+
return `did:handle:${platform.toLowerCase()}:${username}`;
|
|
142
|
+
}
|
|
143
|
+
function normalizeDidKey(input) {
|
|
144
|
+
assertString(input, "input", "INVALID_DID");
|
|
145
|
+
const trimmed = input.trim();
|
|
146
|
+
if (!trimmed.startsWith("did:key:")) {
|
|
147
|
+
throw new OmaTrustError("INVALID_DID", "Expected did:key DID", { input });
|
|
148
|
+
}
|
|
149
|
+
return trimmed;
|
|
150
|
+
}
|
|
151
|
+
function normalizeDid(input) {
|
|
152
|
+
assertString(input, "input", "INVALID_DID");
|
|
153
|
+
const trimmed = input.trim();
|
|
154
|
+
if (!trimmed.startsWith("did:")) {
|
|
155
|
+
return normalizeDidWeb(trimmed);
|
|
156
|
+
}
|
|
157
|
+
if (!isValidDid(trimmed)) {
|
|
158
|
+
throw new OmaTrustError("INVALID_DID", "Invalid DID format", { input });
|
|
159
|
+
}
|
|
160
|
+
const method = extractDidMethod(trimmed);
|
|
161
|
+
switch (method) {
|
|
162
|
+
case "web":
|
|
163
|
+
return normalizeDidWeb(trimmed);
|
|
164
|
+
case "pkh":
|
|
165
|
+
return normalizeDidPkh(trimmed);
|
|
166
|
+
case "handle":
|
|
167
|
+
return normalizeDidHandle(trimmed);
|
|
168
|
+
case "key":
|
|
169
|
+
return normalizeDidKey(trimmed);
|
|
170
|
+
default:
|
|
171
|
+
return trimmed;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function computeDidHash(did) {
|
|
175
|
+
const normalized = normalizeDid(did);
|
|
176
|
+
return keccak256(toUtf8Bytes(normalized));
|
|
177
|
+
}
|
|
178
|
+
function computeDidAddress(didHash) {
|
|
179
|
+
assertString(didHash, "didHash", "INVALID_DID");
|
|
180
|
+
if (!/^0x[0-9a-fA-F]{64}$/.test(didHash)) {
|
|
181
|
+
throw new OmaTrustError("INVALID_DID", "didHash must be 32-byte hex", { didHash });
|
|
182
|
+
}
|
|
183
|
+
const truncated = `0x${didHash.slice(-40)}`;
|
|
184
|
+
return getAddress(truncated);
|
|
185
|
+
}
|
|
186
|
+
function didToAddress(did) {
|
|
187
|
+
return computeDidAddress(computeDidHash(did));
|
|
188
|
+
}
|
|
189
|
+
function validateDidAddress(did, address) {
|
|
190
|
+
try {
|
|
191
|
+
return didToAddress(did).toLowerCase() === String(address).toLowerCase();
|
|
192
|
+
} catch {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function buildDidWeb(domain) {
|
|
197
|
+
return `did:web:${normalizeDomain(domain)}`;
|
|
198
|
+
}
|
|
199
|
+
function buildDidPkh(namespace, chainId, address) {
|
|
200
|
+
assertString(namespace, "namespace", "INVALID_DID");
|
|
201
|
+
assertString(address, "address", "INVALID_DID");
|
|
202
|
+
if (chainId === "" || chainId === null || chainId === void 0) {
|
|
203
|
+
throw new OmaTrustError("INVALID_DID", "chainId is required", { chainId });
|
|
204
|
+
}
|
|
205
|
+
return `did:pkh:${namespace.toLowerCase()}:${chainId}:${address.toLowerCase()}`;
|
|
206
|
+
}
|
|
207
|
+
function buildEvmDidPkh(chainId, address) {
|
|
208
|
+
return buildDidPkh("eip155", chainId, address);
|
|
209
|
+
}
|
|
210
|
+
function buildDidPkhFromCaip10(caip10) {
|
|
211
|
+
const parsed = parseCaip10(caip10);
|
|
212
|
+
return buildDidPkh(parsed.namespace, parsed.reference, parsed.address);
|
|
213
|
+
}
|
|
214
|
+
function parseDidPkh(did) {
|
|
215
|
+
if (!did.startsWith("did:pkh:")) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
const parts = did.split(":");
|
|
219
|
+
if (parts.length !== 5) {
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
const [, , namespace, chainId, address] = parts;
|
|
223
|
+
if (!namespace || !chainId || !address) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
return { namespace, chainId, address };
|
|
227
|
+
}
|
|
228
|
+
function getChainIdFromDidPkh(did) {
|
|
229
|
+
return parseDidPkh(did)?.chainId ?? null;
|
|
230
|
+
}
|
|
231
|
+
function getAddressFromDidPkh(did) {
|
|
232
|
+
return parseDidPkh(did)?.address ?? null;
|
|
233
|
+
}
|
|
234
|
+
function getNamespaceFromDidPkh(did) {
|
|
235
|
+
return parseDidPkh(did)?.namespace ?? null;
|
|
236
|
+
}
|
|
237
|
+
function isEvmDidPkh(did) {
|
|
238
|
+
return getNamespaceFromDidPkh(did) === "eip155";
|
|
239
|
+
}
|
|
240
|
+
function getDomainFromDidWeb(did) {
|
|
241
|
+
if (!did.startsWith("did:web:")) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
const identifier = did.slice("did:web:".length);
|
|
245
|
+
const [domain] = identifier.split("/");
|
|
246
|
+
return domain || null;
|
|
247
|
+
}
|
|
248
|
+
function extractAddressFromDid(identifier) {
|
|
249
|
+
assertString(identifier, "identifier", "INVALID_DID");
|
|
250
|
+
if (identifier.startsWith("did:pkh:")) {
|
|
251
|
+
const pkh = parseDidPkh(normalizeDidPkh(identifier));
|
|
252
|
+
if (!pkh) {
|
|
253
|
+
throw new OmaTrustError("INVALID_DID", "Invalid did:pkh identifier", { identifier });
|
|
254
|
+
}
|
|
255
|
+
return pkh.address;
|
|
256
|
+
}
|
|
257
|
+
if (identifier.startsWith("did:ethr:")) {
|
|
258
|
+
const parts = identifier.replace("did:ethr:", "").split(":");
|
|
259
|
+
const address = parts.length === 1 ? parts[0] : parts[1];
|
|
260
|
+
if (!address || !isAddress(address)) {
|
|
261
|
+
throw new OmaTrustError("INVALID_DID", "Invalid did:ethr identifier", { identifier });
|
|
262
|
+
}
|
|
263
|
+
return getAddress(address);
|
|
264
|
+
}
|
|
265
|
+
if (identifier.match(/^[a-z0-9-]+:[a-zA-Z0-9-]+:0x[a-fA-F0-9]{40}$/)) {
|
|
266
|
+
const parsed = parseCaip10(identifier);
|
|
267
|
+
return parsed.address;
|
|
268
|
+
}
|
|
269
|
+
if (isAddress(identifier)) {
|
|
270
|
+
return getAddress(identifier);
|
|
271
|
+
}
|
|
272
|
+
throw new OmaTrustError("INVALID_DID", "Unsupported identifier format", { identifier });
|
|
273
|
+
}
|
|
274
|
+
function canonicalizeJson(obj) {
|
|
275
|
+
const jcs = canonicalize(obj);
|
|
276
|
+
if (!jcs) {
|
|
277
|
+
throw new OmaTrustError("INVALID_INPUT", "Object cannot be canonicalized", { obj });
|
|
278
|
+
}
|
|
279
|
+
return jcs;
|
|
280
|
+
}
|
|
281
|
+
function canonicalizeForHash(obj) {
|
|
282
|
+
const jcsJson = canonicalizeJson(obj);
|
|
283
|
+
return {
|
|
284
|
+
jcsJson,
|
|
285
|
+
hash: keccak256(toUtf8Bytes(jcsJson))
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function hashCanonicalizedJson(obj, algorithm) {
|
|
289
|
+
const jcs = canonicalizeJson(obj);
|
|
290
|
+
const bytes = toUtf8Bytes(jcs);
|
|
291
|
+
return algorithm === "keccak256" ? keccak256(bytes) : sha256(bytes);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export { buildCaip10, buildCaip2, buildDidPkh, buildDidPkhFromCaip10, buildDidWeb, buildEvmDidPkh, canonicalizeForHash, canonicalizeJson, computeDidAddress, computeDidHash, didToAddress, extractAddressFromDid, extractDidIdentifier, extractDidMethod, getAddressFromDidPkh, getChainIdFromDidPkh, getDomainFromDidWeb, getNamespaceFromDidPkh, hashCanonicalizedJson, isEvmDidPkh, isValidDid, normalizeCaip10, normalizeDid, normalizeDidHandle, normalizeDidKey, normalizeDidPkh, normalizeDidWeb, normalizeDomain, parseCaip10, parseCaip2, validateDidAddress };
|
|
295
|
+
//# sourceMappingURL=index.js.map
|
|
296
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/shared/errors.ts","../../src/shared/assert.ts","../../src/identity/caip.ts","../../src/identity/did.ts","../../src/identity/data.ts"],"names":["keccak256","toUtf8Bytes"],"mappings":"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","file":"index.js","sourcesContent":["export class OmaTrustError extends Error {\n code: string;\n details?: unknown;\n\n constructor(code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"OmaTrustError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toOmaTrustError(\n code: string,\n message: string,\n details?: unknown\n): OmaTrustError {\n return new OmaTrustError(code, message, details);\n}\n","import { OmaTrustError } from \"./errors\";\n\nexport function assertString(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new OmaTrustError(code, `${name} must be a non-empty string`, { value });\n }\n}\n\nexport function assertNumber(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is number {\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new OmaTrustError(code, `${name} must be a valid number`, { value });\n }\n}\n\nexport function assertObject(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new OmaTrustError(code, `${name} must be an object`, { value });\n }\n}\n\nexport function asError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n return new Error(String(err));\n}\n","import { OmaTrustError } from \"../shared/errors\";\nimport { assertString } from \"../shared/assert\";\n\nexport type Caip10 = string;\n\nexport type ParsedCaip10 = {\n namespace: string;\n reference: string;\n address: string;\n};\n\nexport type ParsedCaip2 = {\n namespace: string;\n reference: string;\n};\n\nconst CAIP_10_REGEX = /^(?<namespace>[a-z0-9-]+):(?<reference>[a-zA-Z0-9-]+):(?<address>.+)$/;\nconst CAIP_2_REGEX = /^(?<namespace>[a-z0-9-]+):(?<reference>[a-zA-Z0-9-]+)$/;\n\nexport function parseCaip10(input: string): ParsedCaip10 {\n assertString(input, \"input\", \"INVALID_CAIP\");\n const trimmed = input.trim();\n const match = trimmed.match(CAIP_10_REGEX);\n if (!match?.groups) {\n throw new OmaTrustError(\"INVALID_CAIP\", \"Invalid CAIP-10 format\", { input });\n }\n\n const namespace = match.groups.namespace;\n const reference = match.groups.reference;\n const address = match.groups.address;\n\n if (!namespace || !reference || !address) {\n throw new OmaTrustError(\"INVALID_CAIP\", \"Invalid CAIP-10 components\", { input });\n }\n\n return { namespace, reference, address };\n}\n\nexport function buildCaip10(namespace: string, reference: string, address: string): Caip10 {\n assertString(namespace, \"namespace\", \"INVALID_CAIP\");\n assertString(reference, \"reference\", \"INVALID_CAIP\");\n assertString(address, \"address\", \"INVALID_CAIP\");\n return `${namespace}:${reference}:${address}`;\n}\n\nexport function normalizeCaip10(input: string): Caip10 {\n const parsed = parseCaip10(input);\n const namespace = parsed.namespace.toLowerCase();\n const reference = parsed.reference;\n\n let address = parsed.address;\n if (namespace === \"eip155\") {\n address = address.toLowerCase();\n }\n\n return buildCaip10(namespace, reference, address);\n}\n\nexport function buildCaip2(namespace: string, reference: string): string {\n assertString(namespace, \"namespace\", \"INVALID_CAIP\");\n assertString(reference, \"reference\", \"INVALID_CAIP\");\n return `${namespace}:${reference}`;\n}\n\nexport function parseCaip2(caip2: string): ParsedCaip2 {\n assertString(caip2, \"caip2\", \"INVALID_CAIP\");\n const trimmed = caip2.trim();\n const match = trimmed.match(CAIP_2_REGEX);\n if (!match?.groups) {\n throw new OmaTrustError(\"INVALID_CAIP\", \"Invalid CAIP-2 format\", { caip2 });\n }\n\n const namespace = match.groups.namespace;\n const reference = match.groups.reference;\n if (!namespace || !reference) {\n throw new OmaTrustError(\"INVALID_CAIP\", \"Invalid CAIP-2 components\", { caip2 });\n }\n\n return { namespace, reference };\n}\n","import { getAddress, isAddress, keccak256, toUtf8Bytes } from \"ethers\";\nimport { OmaTrustError } from \"../shared/errors\";\nimport { assertString } from \"../shared/assert\";\nimport { parseCaip10 } from \"./caip\";\n\nexport type Hex = `0x${string}`;\nexport type Did = string;\n\nconst DID_REGEX = /^did:[a-z0-9]+:.+$/i;\n\nexport function isValidDid(did: string): boolean {\n return DID_REGEX.test(did);\n}\n\nexport function extractDidMethod(did: Did): string | null {\n const match = did.match(/^did:([a-z0-9]+):/i);\n return match ? match[1] : null;\n}\n\nexport function extractDidIdentifier(did: Did): string | null {\n const match = did.match(/^did:[a-z0-9]+:(.+)$/i);\n return match ? match[1] : null;\n}\n\nexport function normalizeDomain(domain: string): string {\n assertString(domain, \"domain\", \"INVALID_DID\");\n return domain.trim().toLowerCase().replace(/\\.$/, \"\");\n}\n\nexport function normalizeDidWeb(input: string): Did {\n assertString(input, \"input\", \"INVALID_DID\");\n const trimmed = input.trim();\n\n if (trimmed.startsWith(\"did:\") && !trimmed.startsWith(\"did:web:\")) {\n throw new OmaTrustError(\"INVALID_DID\", \"Expected did:web DID\", { input });\n }\n\n const identifier = trimmed.startsWith(\"did:web:\")\n ? trimmed.slice(\"did:web:\".length)\n : trimmed;\n\n const [host, ...pathParts] = identifier.split(\"/\");\n if (!host) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid did:web identifier\", { input });\n }\n\n const normalizedHost = normalizeDomain(host);\n const path = pathParts.length > 0 ? `/${pathParts.join(\"/\")}` : \"\";\n return `did:web:${normalizedHost}${path}`;\n}\n\nexport function normalizeDidPkh(input: string): Did {\n assertString(input, \"input\", \"INVALID_DID\");\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"did:pkh:\")) {\n throw new OmaTrustError(\"INVALID_DID\", \"Expected did:pkh DID\", { input });\n }\n\n const parts = trimmed.split(\":\");\n if (parts.length !== 5) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid did:pkh format\", { input });\n }\n\n const [, , namespace, chainId, address] = parts;\n if (!namespace || !chainId || !address) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid did:pkh components\", { input });\n }\n\n return `did:pkh:${namespace.toLowerCase()}:${chainId}:${address.toLowerCase()}`;\n}\n\nexport function normalizeDidHandle(input: string): Did {\n assertString(input, \"input\", \"INVALID_DID\");\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"did:handle:\")) {\n throw new OmaTrustError(\"INVALID_DID\", \"Expected did:handle DID\", { input });\n }\n\n const parts = trimmed.split(\":\");\n if (parts.length !== 4) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid did:handle format\", { input });\n }\n\n const [, , platform, username] = parts;\n if (!platform || !username) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid did:handle components\", { input });\n }\n\n return `did:handle:${platform.toLowerCase()}:${username}`;\n}\n\nexport function normalizeDidKey(input: string): Did {\n assertString(input, \"input\", \"INVALID_DID\");\n const trimmed = input.trim();\n if (!trimmed.startsWith(\"did:key:\")) {\n throw new OmaTrustError(\"INVALID_DID\", \"Expected did:key DID\", { input });\n }\n\n return trimmed;\n}\n\nexport function normalizeDid(input: string): Did {\n assertString(input, \"input\", \"INVALID_DID\");\n const trimmed = input.trim();\n\n if (!trimmed.startsWith(\"did:\")) {\n return normalizeDidWeb(trimmed);\n }\n\n if (!isValidDid(trimmed)) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid DID format\", { input });\n }\n\n const method = extractDidMethod(trimmed);\n switch (method) {\n case \"web\":\n return normalizeDidWeb(trimmed);\n case \"pkh\":\n return normalizeDidPkh(trimmed);\n case \"handle\":\n return normalizeDidHandle(trimmed);\n case \"key\":\n return normalizeDidKey(trimmed);\n default:\n return trimmed;\n }\n}\n\nexport function computeDidHash(did: Did): Hex {\n const normalized = normalizeDid(did);\n return keccak256(toUtf8Bytes(normalized)) as Hex;\n}\n\nexport function computeDidAddress(didHash: Hex): Hex {\n assertString(didHash, \"didHash\", \"INVALID_DID\");\n if (!/^0x[0-9a-fA-F]{64}$/.test(didHash)) {\n throw new OmaTrustError(\"INVALID_DID\", \"didHash must be 32-byte hex\", { didHash });\n }\n\n const truncated = `0x${didHash.slice(-40)}`;\n return getAddress(truncated) as Hex;\n}\n\nexport function didToAddress(did: Did): Hex {\n return computeDidAddress(computeDidHash(did));\n}\n\nexport function validateDidAddress(did: Did, address: Hex): boolean {\n try {\n return didToAddress(did).toLowerCase() === String(address).toLowerCase();\n } catch {\n return false;\n }\n}\n\nexport function buildDidWeb(domain: string): Did {\n return `did:web:${normalizeDomain(domain)}`;\n}\n\nexport function buildDidPkh(\n namespace: string,\n chainId: string | number,\n address: string\n): Did {\n assertString(namespace, \"namespace\", \"INVALID_DID\");\n assertString(address, \"address\", \"INVALID_DID\");\n if (chainId === \"\" || chainId === null || chainId === undefined) {\n throw new OmaTrustError(\"INVALID_DID\", \"chainId is required\", { chainId });\n }\n return `did:pkh:${namespace.toLowerCase()}:${chainId}:${address.toLowerCase()}`;\n}\n\nexport function buildEvmDidPkh(chainId: string | number, address: string): Did {\n return buildDidPkh(\"eip155\", chainId, address);\n}\n\nexport function buildDidPkhFromCaip10(caip10: string): Did {\n const parsed = parseCaip10(caip10);\n return buildDidPkh(parsed.namespace, parsed.reference, parsed.address);\n}\n\nfunction parseDidPkh(did: Did): { namespace: string; chainId: string; address: string } | null {\n if (!did.startsWith(\"did:pkh:\")) {\n return null;\n }\n\n const parts = did.split(\":\");\n if (parts.length !== 5) {\n return null;\n }\n\n const [, , namespace, chainId, address] = parts;\n if (!namespace || !chainId || !address) {\n return null;\n }\n\n return { namespace, chainId, address };\n}\n\nexport function getChainIdFromDidPkh(did: Did): string | null {\n return parseDidPkh(did)?.chainId ?? null;\n}\n\nexport function getAddressFromDidPkh(did: Did): string | null {\n return parseDidPkh(did)?.address ?? null;\n}\n\nexport function getNamespaceFromDidPkh(did: Did): string | null {\n return parseDidPkh(did)?.namespace ?? null;\n}\n\nexport function isEvmDidPkh(did: Did): boolean {\n return getNamespaceFromDidPkh(did) === \"eip155\";\n}\n\nexport function getDomainFromDidWeb(did: Did): string | null {\n if (!did.startsWith(\"did:web:\")) {\n return null;\n }\n\n const identifier = did.slice(\"did:web:\".length);\n const [domain] = identifier.split(\"/\");\n return domain || null;\n}\n\nexport function extractAddressFromDid(identifier: string): string {\n assertString(identifier, \"identifier\", \"INVALID_DID\");\n\n if (identifier.startsWith(\"did:pkh:\")) {\n const pkh = parseDidPkh(normalizeDidPkh(identifier));\n if (!pkh) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid did:pkh identifier\", { identifier });\n }\n return pkh.address;\n }\n\n if (identifier.startsWith(\"did:ethr:\")) {\n const parts = identifier.replace(\"did:ethr:\", \"\").split(\":\");\n const address = parts.length === 1 ? parts[0] : parts[1];\n if (!address || !isAddress(address)) {\n throw new OmaTrustError(\"INVALID_DID\", \"Invalid did:ethr identifier\", { identifier });\n }\n return getAddress(address);\n }\n\n if (identifier.match(/^[a-z0-9-]+:[a-zA-Z0-9-]+:0x[a-fA-F0-9]{40}$/)) {\n const parsed = parseCaip10(identifier);\n return parsed.address;\n }\n\n if (isAddress(identifier)) {\n return getAddress(identifier);\n }\n\n throw new OmaTrustError(\"INVALID_DID\", \"Unsupported identifier format\", { identifier });\n}\n","import canonicalize from \"canonicalize\";\nimport { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\n\nexport function canonicalizeJson(obj: unknown): string {\n const jcs = canonicalize(obj);\n if (!jcs) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Object cannot be canonicalized\", { obj });\n }\n return jcs;\n}\n\nexport function canonicalizeForHash(obj: unknown): { jcsJson: string; hash: Hex } {\n const jcsJson = canonicalizeJson(obj);\n return {\n jcsJson,\n hash: keccak256(toUtf8Bytes(jcsJson)) as Hex\n };\n}\n\nexport function hashCanonicalizedJson(obj: unknown, algorithm: \"keccak256\" | \"sha256\"): Hex {\n const jcs = canonicalizeJson(obj);\n const bytes = toUtf8Bytes(jcs);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n"]}
|