@oma3/omatrust 0.1.0-alpha.10 → 0.1.0-alpha.11
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/identity/index.cjs +543 -0
- package/dist/identity/index.cjs.map +1 -1
- package/dist/identity/index.d.cts +2 -1
- package/dist/identity/index.d.ts +2 -1
- package/dist/identity/index.js +527 -1
- package/dist/identity/index.js.map +1 -1
- package/dist/index-BOvk-7Ku.d.cts +235 -0
- package/dist/index-C2w5EvFH.d.ts +329 -0
- package/dist/index-QueRiudB.d.cts +329 -0
- package/dist/index-R78TpAhN.d.ts +235 -0
- package/dist/index.cjs +1475 -165
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +1476 -166
- package/dist/index.js.map +1 -1
- package/dist/reputation/index.browser.cjs +943 -66
- package/dist/reputation/index.browser.cjs.map +1 -1
- package/dist/reputation/index.browser.d.cts +2 -2
- package/dist/reputation/index.browser.d.ts +2 -2
- package/dist/reputation/index.browser.js +941 -66
- package/dist/reputation/index.browser.js.map +1 -1
- package/dist/reputation/index.cjs +1393 -217
- package/dist/reputation/index.cjs.map +1 -1
- package/dist/reputation/index.d.cts +3 -2
- package/dist/reputation/index.d.ts +3 -2
- package/dist/reputation/index.js +1378 -217
- package/dist/reputation/index.js.map +1 -1
- package/dist/{subject-ownership-CXvzEjpH.d.cts → subject-ownership-B7cFlm8c.d.cts} +256 -26
- package/dist/{subject-ownership-CXvzEjpH.d.ts → subject-ownership-B7cFlm8c.d.ts} +256 -26
- package/dist/types-dpYxRq8N.d.cts +281 -0
- package/dist/types-dpYxRq8N.d.ts +281 -0
- package/dist/widgets/index.cjs +70 -27
- package/dist/widgets/index.cjs.map +1 -1
- package/dist/widgets/index.d.cts +42 -18
- package/dist/widgets/index.d.ts +42 -18
- package/dist/widgets/index.js +67 -26
- package/dist/widgets/index.js.map +1 -1
- package/package.json +3 -2
- package/dist/index-B9KW02US.d.cts +0 -119
- package/dist/index-DXrwBex9.d.ts +0 -119
- package/dist/index-QZDExA4I.d.cts +0 -90
- package/dist/index-QZDExA4I.d.ts +0 -90
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JWK and did:jwk Helpers — Phase 2
|
|
3
|
+
*
|
|
4
|
+
* Provides conversion between public JWKs and did:jwk DIDs,
|
|
5
|
+
* deterministic JWK comparison, and public JWK validation.
|
|
6
|
+
*
|
|
7
|
+
* did:jwk is the preferred durable DID representation for JWS/JWK public key
|
|
8
|
+
* material. It is immutable (the DID IS the key) and should be used as the
|
|
9
|
+
* controllerDid for authorization checks.
|
|
10
|
+
*
|
|
11
|
+
* Uses the `jose` library for base64url encoding/decoding and JWK thumbprints.
|
|
12
|
+
*/
|
|
13
|
+
/** Minimal public JWK structure */
|
|
14
|
+
interface PublicJwk {
|
|
15
|
+
kty: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
/** Result of JWK validation */
|
|
19
|
+
interface JwkValidationResult {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Validate that a JWK object is a well-formed public key.
|
|
25
|
+
*
|
|
26
|
+
* Requirements:
|
|
27
|
+
* - Must be a non-null object
|
|
28
|
+
* - Must have a valid `kty` (EC, OKP, RSA)
|
|
29
|
+
* - Must have required public key fields for its key type
|
|
30
|
+
* - Must NOT contain private key material (d, p, q, dp, dq, qi, oth)
|
|
31
|
+
*/
|
|
32
|
+
declare function validatePublicJwk(jwk: unknown): JwkValidationResult;
|
|
33
|
+
/**
|
|
34
|
+
* Convert a public JWK to a did:jwk DID.
|
|
35
|
+
*
|
|
36
|
+
* Uses deterministic (sorted-key) JSON serialization and base64url encoding.
|
|
37
|
+
* Rejects JWKs containing private key material.
|
|
38
|
+
*
|
|
39
|
+
* @param jwk - A public JWK object
|
|
40
|
+
* @returns The did:jwk DID string
|
|
41
|
+
* @throws OmaTrustError if the JWK is invalid or contains private key material
|
|
42
|
+
*/
|
|
43
|
+
declare function jwkToDidJwk(jwk: unknown): string;
|
|
44
|
+
/**
|
|
45
|
+
* Convert a did:jwk DID back to a public JWK object.
|
|
46
|
+
*
|
|
47
|
+
* Validates the DID structure, decodes the base64url payload,
|
|
48
|
+
* parses JSON, and validates the resulting JWK.
|
|
49
|
+
*
|
|
50
|
+
* @param didJwk - A did:jwk DID string
|
|
51
|
+
* @returns The decoded public JWK object
|
|
52
|
+
* @throws OmaTrustError if the DID is malformed or contains private key material
|
|
53
|
+
*/
|
|
54
|
+
declare function didJwkToJwk(didJwk: string): PublicJwk;
|
|
55
|
+
/**
|
|
56
|
+
* Compare two public JWKs for equality.
|
|
57
|
+
*
|
|
58
|
+
* Compares only the public key material fields (kty, crv, x, y, n, e, etc.).
|
|
59
|
+
* Ignores property order, metadata fields (kid, use, alg, key_ops, ext),
|
|
60
|
+
* and rejects/strips private key fields before comparison.
|
|
61
|
+
*
|
|
62
|
+
* @param a - First public JWK
|
|
63
|
+
* @param b - Second public JWK
|
|
64
|
+
* @returns true if both JWKs represent the same public key
|
|
65
|
+
* @throws OmaTrustError if either JWK contains private key material
|
|
66
|
+
*/
|
|
67
|
+
declare function publicJwkEquals(a: unknown, b: unknown): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Compute an RFC 7638 JWK Thumbprint for a public JWK.
|
|
70
|
+
*
|
|
71
|
+
* Returns the base64url-encoded SHA-256 thumbprint. This is a compact,
|
|
72
|
+
* deterministic fingerprint of the public key material.
|
|
73
|
+
*
|
|
74
|
+
* Used in OMATrust DNS TXT records as: `jkt=S256:<thumbprint>`
|
|
75
|
+
*
|
|
76
|
+
* @param jwk - A public JWK object
|
|
77
|
+
* @param digestAlgorithm - Hash algorithm (default: "sha256")
|
|
78
|
+
* @returns base64url-encoded thumbprint string
|
|
79
|
+
* @throws OmaTrustError if the JWK is invalid or contains private key material
|
|
80
|
+
*/
|
|
81
|
+
declare function computeJwkThumbprint(jwk: unknown, digestAlgorithm?: "sha256" | "sha384" | "sha512"): Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Format a JWK thumbprint as an OMATrust DNS TXT `jkt` value.
|
|
84
|
+
*
|
|
85
|
+
* Format: `jkt=S256:<base64url-thumbprint>`
|
|
86
|
+
*
|
|
87
|
+
* @param jwk - A public JWK object
|
|
88
|
+
* @returns Formatted jkt string for DNS TXT records
|
|
89
|
+
*/
|
|
90
|
+
declare function formatJktValue(jwk: unknown): Promise<string>;
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* DID URL Key Resolution — Phase 3
|
|
94
|
+
*
|
|
95
|
+
* Resolves DID URL key references (e.g. did:web:api.example.com#key-1) to
|
|
96
|
+
* public key material and derives durable did:jwk controller DIDs.
|
|
97
|
+
*
|
|
98
|
+
* DID URLs are mutable key references. This module resolves them to the
|
|
99
|
+
* actual public key material they currently point to, then converts that
|
|
100
|
+
* material into an immutable did:jwk for use as a controller DID.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
/** Result of resolving a DID URL to public key material */
|
|
104
|
+
interface ResolvedPublicKey {
|
|
105
|
+
/** The original DID URL */
|
|
106
|
+
didUrl: string;
|
|
107
|
+
/** The base DID (without fragment) */
|
|
108
|
+
did: string;
|
|
109
|
+
/** The fragment identifier */
|
|
110
|
+
fragment: string | null;
|
|
111
|
+
/** The resolved public JWK */
|
|
112
|
+
publicKeyJwk: PublicJwk;
|
|
113
|
+
/** The verification method ID that matched */
|
|
114
|
+
verificationMethodId: string;
|
|
115
|
+
}
|
|
116
|
+
/** Result of resolving a DID URL to a durable controller DID */
|
|
117
|
+
interface ResolvedControllerDid extends ResolvedPublicKey {
|
|
118
|
+
/** The durable did:jwk derived from the resolved public key */
|
|
119
|
+
controllerDid: string;
|
|
120
|
+
}
|
|
121
|
+
/** Options for DID URL key resolution */
|
|
122
|
+
interface ResolveKeyOptions {
|
|
123
|
+
/**
|
|
124
|
+
* Custom DID document fetcher. If not provided, uses the shared
|
|
125
|
+
* fetchDidDocument which fetches from `/.well-known/did.json`.
|
|
126
|
+
*/
|
|
127
|
+
fetchDidDocument?: (domain: string) => Promise<Record<string, unknown>>;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Resolve a DID URL to public key material.
|
|
131
|
+
*
|
|
132
|
+
* Currently supports:
|
|
133
|
+
* - did:web with fragment (e.g. did:web:api.example.com#key-1)
|
|
134
|
+
*
|
|
135
|
+
* Resolution steps:
|
|
136
|
+
* 1. Parse the DID URL
|
|
137
|
+
* 2. Resolve the base DID (fetch DID document)
|
|
138
|
+
* 3. Find the matching verification method
|
|
139
|
+
* 4. Extract and validate publicKeyJwk
|
|
140
|
+
*
|
|
141
|
+
* This function only obtains key material. It does not make authorization
|
|
142
|
+
* decisions or check Controller Witness / Key Binding records.
|
|
143
|
+
*
|
|
144
|
+
* @param didUrl - A DID URL string (e.g. "did:web:api.example.com#key-1")
|
|
145
|
+
* @param options - Optional configuration (custom fetcher, etc.)
|
|
146
|
+
* @returns Resolved public key information
|
|
147
|
+
* @throws OmaTrustError if resolution fails
|
|
148
|
+
*/
|
|
149
|
+
declare function resolveDidUrlToPublicKey(didUrl: string, options?: ResolveKeyOptions): Promise<ResolvedPublicKey>;
|
|
150
|
+
/**
|
|
151
|
+
* Resolve a DID URL to a durable controller DID.
|
|
152
|
+
*
|
|
153
|
+
* This wraps resolveDidUrlToPublicKey and adds the did:jwk conversion step.
|
|
154
|
+
* The returned controllerDid is the durable DID that callers should pass
|
|
155
|
+
* to getControllerAuthorization.
|
|
156
|
+
*
|
|
157
|
+
* @param didUrl - A DID URL string (e.g. "did:web:api.example.com#key-1")
|
|
158
|
+
* @param options - Optional configuration (custom fetcher, etc.)
|
|
159
|
+
* @returns Resolved public key plus derived did:jwk controller DID
|
|
160
|
+
* @throws OmaTrustError if resolution fails
|
|
161
|
+
*/
|
|
162
|
+
declare function resolveDidUrlToControllerDid(didUrl: string, options?: ResolveKeyOptions): Promise<ResolvedControllerDid>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Identity Types — Phase 4
|
|
166
|
+
*
|
|
167
|
+
* Types for JWS verification results and authorization metadata.
|
|
168
|
+
* These define the contract between signature verification and
|
|
169
|
+
* downstream authorization checks via getControllerAuthorization.
|
|
170
|
+
*/
|
|
171
|
+
|
|
172
|
+
/** Source of the public key used for JWS signature verification */
|
|
173
|
+
type PublicKeySource = "embedded-jwk" | "kid-resolution";
|
|
174
|
+
/**
|
|
175
|
+
* Structured result of JWS signature verification.
|
|
176
|
+
*
|
|
177
|
+
* This result is NOT an authorization result. It does not determine whether
|
|
178
|
+
* the signing key was authorized to act for the service identified by resourceUrl.
|
|
179
|
+
*
|
|
180
|
+
* It provides enough information for callers to perform downstream authorization
|
|
181
|
+
* checks via getControllerAuthorization:
|
|
182
|
+
* - publicKeyDid (did:jwk) is the durable controller DID
|
|
183
|
+
* - resourceUrl identifies the service subject
|
|
184
|
+
* - issuedAt enables authorization-window checks for receipts
|
|
185
|
+
*/
|
|
186
|
+
interface JwsVerificationResult {
|
|
187
|
+
/** Whether the JWS signature is cryptographically valid */
|
|
188
|
+
valid: boolean;
|
|
189
|
+
/** Decoded JWS protected header */
|
|
190
|
+
header: Record<string, unknown>;
|
|
191
|
+
/** Decoded JWS payload */
|
|
192
|
+
payload: Record<string, unknown>;
|
|
193
|
+
/** kid from the JWS header (a key reference, NOT a controller DID) */
|
|
194
|
+
kid: string | null;
|
|
195
|
+
/** The public JWK used for signature verification */
|
|
196
|
+
publicKeyJwk: PublicJwk;
|
|
197
|
+
/** How the public key was obtained */
|
|
198
|
+
publicKeySource: PublicKeySource;
|
|
199
|
+
/**
|
|
200
|
+
* The durable did:jwk derived from the public key.
|
|
201
|
+
* This is the controller DID for downstream authorization checks.
|
|
202
|
+
* Pass this as controllerDid to getControllerAuthorization.
|
|
203
|
+
*/
|
|
204
|
+
publicKeyDid: string;
|
|
205
|
+
/** Error details when valid is false */
|
|
206
|
+
error?: JwsVerificationError;
|
|
207
|
+
}
|
|
208
|
+
/** Error details for failed JWS verification */
|
|
209
|
+
interface JwsVerificationError {
|
|
210
|
+
code: string;
|
|
211
|
+
message: string;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Failed JWS verification result.
|
|
215
|
+
* Returned when parsing, decoding, or signature verification fails.
|
|
216
|
+
*/
|
|
217
|
+
interface JwsVerificationFailure {
|
|
218
|
+
valid: false;
|
|
219
|
+
error: JwsVerificationError;
|
|
220
|
+
header?: Record<string, unknown>;
|
|
221
|
+
payload?: Record<string, unknown>;
|
|
222
|
+
kid?: string | null;
|
|
223
|
+
publicKeyJwk?: PublicJwk;
|
|
224
|
+
publicKeySource?: PublicKeySource;
|
|
225
|
+
publicKeyDid?: string;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Authorization metadata extracted from a verified JWS artifact.
|
|
229
|
+
*
|
|
230
|
+
* This is the information a caller needs to perform an authorization check
|
|
231
|
+
* after JWS signature verification succeeds.
|
|
232
|
+
*
|
|
233
|
+
* Usage:
|
|
234
|
+
* 1. Verify JWS → get JwsVerificationResult
|
|
235
|
+
* 2. Extract AuthorizationMetadata from the result
|
|
236
|
+
* 3. Call getControllerAuthorization({ subjectDid, controllerDid, purpose })
|
|
237
|
+
* 4. Evaluate the returned authorization window against policy
|
|
238
|
+
*/
|
|
239
|
+
interface AuthorizationMetadata {
|
|
240
|
+
/**
|
|
241
|
+
* The durable controller DID (did:jwk) derived from the verified public key.
|
|
242
|
+
* Pass this as controllerDid to getControllerAuthorization.
|
|
243
|
+
*/
|
|
244
|
+
controllerDid: string;
|
|
245
|
+
/**
|
|
246
|
+
* The subject DID derived from resourceUrl.
|
|
247
|
+
* For x402 artifacts, this is typically did:web:<domain-from-resourceUrl>.
|
|
248
|
+
* Pass this as subjectDid to getControllerAuthorization.
|
|
249
|
+
*/
|
|
250
|
+
subjectDid: string | null;
|
|
251
|
+
/**
|
|
252
|
+
* The resourceUrl from the signed payload.
|
|
253
|
+
* Identifies the service/resource the artifact is associated with.
|
|
254
|
+
*/
|
|
255
|
+
resourceUrl: string | null;
|
|
256
|
+
/**
|
|
257
|
+
* The issuedAt timestamp from the signed payload (receipts).
|
|
258
|
+
* Used for authorization-window checks — was the controller authorized at this time?
|
|
259
|
+
*/
|
|
260
|
+
issuedAt: string | null;
|
|
261
|
+
/**
|
|
262
|
+
* The kid from the JWS header (mutable key reference).
|
|
263
|
+
* Useful for key-pinning lookups but NOT a controller DID.
|
|
264
|
+
*/
|
|
265
|
+
kid: string | null;
|
|
266
|
+
/** The public JWK used for signature verification */
|
|
267
|
+
publicKeyJwk: PublicJwk;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Extract authorization metadata from a successful JWS verification result.
|
|
271
|
+
*
|
|
272
|
+
* Derives the subject DID from resourceUrl when possible (assumes did:web
|
|
273
|
+
* for HTTPS URLs). Returns null for subjectDid if resourceUrl is missing
|
|
274
|
+
* or cannot be parsed.
|
|
275
|
+
*
|
|
276
|
+
* @param result - A successful JwsVerificationResult (valid === true)
|
|
277
|
+
* @returns Authorization metadata for downstream getControllerAuthorization calls
|
|
278
|
+
*/
|
|
279
|
+
declare function extractAuthorizationMetadata(result: JwsVerificationResult): AuthorizationMetadata;
|
|
280
|
+
|
|
281
|
+
export { type AuthorizationMetadata as A, type JwkValidationResult as J, type PublicJwk as P, type ResolveKeyOptions as R, type JwsVerificationError as a, type JwsVerificationFailure as b, type JwsVerificationResult as c, type PublicKeySource as d, type ResolvedControllerDid as e, type ResolvedPublicKey as f, computeJwkThumbprint as g, didJwkToJwk as h, extractAuthorizationMetadata as i, formatJktValue as j, jwkToDidJwk as k, resolveDidUrlToPublicKey as l, publicJwkEquals as p, resolveDidUrlToControllerDid as r, validatePublicJwk as v };
|
package/dist/widgets/index.cjs
CHANGED
|
@@ -7,35 +7,76 @@ var OMATRUST_SIGN_TYPED_DATA = "omatrust:signTypedData";
|
|
|
7
7
|
var OMATRUST_SIGNATURE = "omatrust:signature";
|
|
8
8
|
var OMATRUST_SIGNATURE_ERROR = "omatrust:signatureError";
|
|
9
9
|
|
|
10
|
-
// src/
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
// src/shared/errors.ts
|
|
11
|
+
var OmaTrustError = class extends Error {
|
|
12
|
+
code;
|
|
13
|
+
details;
|
|
14
|
+
constructor(code, message, details) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "OmaTrustError";
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.details = details;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/shared/trust-anchors.ts
|
|
23
|
+
var DEFAULT_TRUST_ANCHORS_URL = "https://api.omatrust.org/v1/trust-anchors";
|
|
24
|
+
var TRUST_ANCHORS_URL = DEFAULT_TRUST_ANCHORS_URL;
|
|
25
|
+
var cachedAnchors = null;
|
|
14
26
|
var cacheTimestamp = 0;
|
|
15
27
|
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
16
|
-
async function
|
|
28
|
+
async function fetchTrustAnchors(url) {
|
|
17
29
|
const now = Date.now();
|
|
18
|
-
if (
|
|
19
|
-
return
|
|
30
|
+
if (cachedAnchors && now - cacheTimestamp < CACHE_TTL_MS) {
|
|
31
|
+
return cachedAnchors;
|
|
32
|
+
}
|
|
33
|
+
let res;
|
|
34
|
+
try {
|
|
35
|
+
res = await fetch(url ?? TRUST_ANCHORS_URL);
|
|
36
|
+
} catch (err) {
|
|
37
|
+
throw new OmaTrustError("NETWORK_ERROR", "Failed to fetch trust anchors", { err });
|
|
20
38
|
}
|
|
21
|
-
const res = await fetch(url ?? TRUST_POLICY_URL);
|
|
22
39
|
if (!res.ok) {
|
|
23
|
-
throw new
|
|
40
|
+
throw new OmaTrustError("NETWORK_ERROR", `Failed to fetch trust anchors: ${res.status} ${res.statusText}`);
|
|
24
41
|
}
|
|
25
|
-
const
|
|
26
|
-
if (!
|
|
27
|
-
throw new
|
|
42
|
+
const anchors = await res.json();
|
|
43
|
+
if (!anchors.version || !anchors.chains || typeof anchors.chains !== "object") {
|
|
44
|
+
throw new OmaTrustError("INVALID_INPUT", "Invalid trust anchors format");
|
|
28
45
|
}
|
|
29
|
-
|
|
46
|
+
cachedAnchors = anchors;
|
|
30
47
|
cacheTimestamp = now;
|
|
31
|
-
return
|
|
48
|
+
return anchors;
|
|
32
49
|
}
|
|
33
|
-
function
|
|
50
|
+
function getChainAnchors(anchors, caip2) {
|
|
51
|
+
const chain = anchors.chains[caip2];
|
|
52
|
+
if (!chain) {
|
|
53
|
+
throw new OmaTrustError("UNSUPPORTED_CHAIN", `Chain ${caip2} is not in the trust anchors`, {
|
|
54
|
+
caip2,
|
|
55
|
+
supportedChains: Object.keys(anchors.chains)
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return chain;
|
|
59
|
+
}
|
|
60
|
+
function getSchemaAnchor(anchors, caip2, schemaName) {
|
|
61
|
+
const chain = getChainAnchors(anchors, caip2);
|
|
62
|
+
const uid = chain.schemas[schemaName];
|
|
63
|
+
if (!uid) {
|
|
64
|
+
throw new OmaTrustError("INVALID_INPUT", `Schema "${schemaName}" not found in trust anchors for chain ${caip2}`, {
|
|
65
|
+
caip2,
|
|
66
|
+
schemaName,
|
|
67
|
+
availableSchemas: Object.keys(chain.schemas)
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return uid;
|
|
71
|
+
}
|
|
72
|
+
function extractAllowlists(anchors) {
|
|
34
73
|
const contracts = [];
|
|
35
74
|
const schemas = [];
|
|
36
|
-
for (const chain of Object.values(
|
|
75
|
+
for (const chain of Object.values(anchors.chains)) {
|
|
37
76
|
if (chain.easContract) contracts.push(chain.easContract);
|
|
38
|
-
if (chain.schemas
|
|
77
|
+
if (chain.schemas && typeof chain.schemas === "object") {
|
|
78
|
+
schemas.push(...Object.values(chain.schemas));
|
|
79
|
+
}
|
|
39
80
|
}
|
|
40
81
|
return {
|
|
41
82
|
allowedContracts: [...new Set(contracts)],
|
|
@@ -46,7 +87,7 @@ function extractAllowlists(policy) {
|
|
|
46
87
|
// src/widgets/bridge.ts
|
|
47
88
|
function getTrustedBaseDomain() {
|
|
48
89
|
try {
|
|
49
|
-
const hostname = new URL(
|
|
90
|
+
const hostname = new URL(TRUST_ANCHORS_URL).hostname;
|
|
50
91
|
const parts = hostname.split(".");
|
|
51
92
|
return parts.length >= 2 ? parts.slice(-2).join(".") : hostname;
|
|
52
93
|
} catch {
|
|
@@ -89,7 +130,7 @@ function validateEasSigningRequest(data, allowedSchemas, allowedContracts) {
|
|
|
89
130
|
}
|
|
90
131
|
const contractLower = d.verifyingContract.toLowerCase();
|
|
91
132
|
if (!allowedContracts.some((c) => c.toLowerCase() === contractLower)) {
|
|
92
|
-
return { valid: false, reason: `Contract ${d.verifyingContract} is not in the OMA3 trust
|
|
133
|
+
return { valid: false, reason: `Contract ${d.verifyingContract} is not in the OMA3 trust anchors` };
|
|
93
134
|
}
|
|
94
135
|
if (!types || typeof types !== "object") {
|
|
95
136
|
return { valid: false, reason: "Missing types object" };
|
|
@@ -103,7 +144,7 @@ function validateEasSigningRequest(data, allowedSchemas, allowedContracts) {
|
|
|
103
144
|
}
|
|
104
145
|
const schemaLower = m.schema.toLowerCase();
|
|
105
146
|
if (!allowedSchemas.some((s) => s.toLowerCase() === schemaLower)) {
|
|
106
|
-
return { valid: false, reason: `Schema ${m.schema} is not in the OMA3 trust
|
|
147
|
+
return { valid: false, reason: `Schema ${m.schema} is not in the OMA3 trust anchors` };
|
|
107
148
|
}
|
|
108
149
|
if (typeof m.attester !== "string" || !HEX_ADDRESS_RE.test(m.attester)) {
|
|
109
150
|
return { valid: false, reason: `Invalid attester address: ${m.attester}` };
|
|
@@ -120,18 +161,18 @@ function validateEasSigningRequest(data, allowedSchemas, allowedContracts) {
|
|
|
120
161
|
}
|
|
121
162
|
async function createSigningBridge(options) {
|
|
122
163
|
const { iframeId, signTypedData, devOriginOverride } = options;
|
|
123
|
-
const
|
|
124
|
-
const { allowedContracts, allowedSchemas } = extractAllowlists(
|
|
164
|
+
const anchors = await fetchTrustAnchors();
|
|
165
|
+
const { allowedContracts, allowedSchemas } = extractAllowlists(anchors);
|
|
125
166
|
if (allowedContracts.length === 0 || allowedSchemas.length === 0) {
|
|
126
|
-
throw new Error("Trust
|
|
167
|
+
throw new Error("Trust anchors contain no allowed contracts or schemas");
|
|
127
168
|
}
|
|
128
169
|
const baseDomain = getTrustedBaseDomain();
|
|
129
|
-
const
|
|
170
|
+
const anchorOrigins = anchors.widgetOrigins ?? [];
|
|
130
171
|
async function handleMessage(event) {
|
|
131
172
|
const data = event.data;
|
|
132
173
|
if (!data || typeof data !== "object" || typeof data.type !== "string") return;
|
|
133
174
|
if (!String(data.type).startsWith("omatrust:")) return;
|
|
134
|
-
if (!isOriginTrusted(event.origin, baseDomain,
|
|
175
|
+
if (!isOriginTrusted(event.origin, baseDomain, anchorOrigins, devOriginOverride)) {
|
|
135
176
|
return;
|
|
136
177
|
}
|
|
137
178
|
const iframe = document.getElementById(iframeId);
|
|
@@ -187,9 +228,11 @@ exports.OMATRUST_READY = OMATRUST_READY;
|
|
|
187
228
|
exports.OMATRUST_SIGNATURE = OMATRUST_SIGNATURE;
|
|
188
229
|
exports.OMATRUST_SIGNATURE_ERROR = OMATRUST_SIGNATURE_ERROR;
|
|
189
230
|
exports.OMATRUST_SIGN_TYPED_DATA = OMATRUST_SIGN_TYPED_DATA;
|
|
190
|
-
exports.
|
|
231
|
+
exports.TRUST_ANCHORS_URL = TRUST_ANCHORS_URL;
|
|
191
232
|
exports.createSigningBridge = createSigningBridge;
|
|
192
233
|
exports.extractAllowlists = extractAllowlists;
|
|
193
|
-
exports.
|
|
234
|
+
exports.fetchTrustAnchors = fetchTrustAnchors;
|
|
235
|
+
exports.getChainAnchors = getChainAnchors;
|
|
236
|
+
exports.getSchemaAnchor = getSchemaAnchor;
|
|
194
237
|
//# sourceMappingURL=index.cjs.map
|
|
195
238
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/widgets/protocol.ts","../../src/widgets/trust-policy.ts","../../src/widgets/bridge.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * postMessage protocol constants and types for the OMATrust widget bridge.\n *\n * Widget (iframe) → Host:\n * omatrust:ready — widget loaded, requesting handshake\n * omatrust:signTypedData — widget requests EIP-712 signature\n *\n * Host → Widget (iframe):\n * omatrust:hostReady — host acknowledges the widget\n * omatrust:signature — host returns a signature\n * omatrust:signatureError — host reports a signing failure\n */\n\nexport const OMATRUST_READY = \"omatrust:ready\" as const;\nexport const OMATRUST_HOST_READY = \"omatrust:hostReady\" as const;\nexport const OMATRUST_SIGN_TYPED_DATA = \"omatrust:signTypedData\" as const;\nexport const OMATRUST_SIGNATURE = \"omatrust:signature\" as const;\nexport const OMATRUST_SIGNATURE_ERROR = \"omatrust:signatureError\" as const;\n\nexport type OmaTrustReadyMessage = {\n type: typeof OMATRUST_READY;\n};\n\nexport type OmaTrustHostReadyMessage = {\n type: typeof OMATRUST_HOST_READY;\n};\n\nexport type OmaTrustSignTypedDataMessage = {\n type: typeof OMATRUST_SIGN_TYPED_DATA;\n id: string;\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n message: Record<string, unknown>;\n};\n\nexport type OmaTrustSignatureMessage = {\n type: typeof OMATRUST_SIGNATURE;\n id: string;\n signature: string;\n};\n\nexport type OmaTrustSignatureErrorMessage = {\n type: typeof OMATRUST_SIGNATURE_ERROR;\n id: string;\n error: string;\n};\n\nexport type OmaTrustMessage =\n | OmaTrustReadyMessage\n | OmaTrustHostReadyMessage\n | OmaTrustSignTypedDataMessage\n | OmaTrustSignatureMessage\n | OmaTrustSignatureErrorMessage;\n","/**\n * Trust policy: fetches the OMA3 allowlist of EAS contracts and schemas.\n *\n * The bridge uses this to validate signing requests automatically.\n * Developers don't need to maintain their own allowlists.\n */\n\nconst DEFAULT_TRUST_POLICY_URL = \"https://api.omatrust.org/v1/trust-policy\";\n\nexport const TRUST_POLICY_URL = DEFAULT_TRUST_POLICY_URL;\n\nexport type ChainPolicy = {\n name: string;\n easContract: string;\n schemas: string[];\n};\n\nexport type TrustPolicy = {\n version: number;\n updatedAt: string;\n widgetOrigins?: string[];\n chains: Record<string, ChainPolicy>;\n};\n\nlet cachedPolicy: TrustPolicy | null = null;\nlet cacheTimestamp = 0;\nconst CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n/**\n * Fetch the trust policy from the OMA3 API gateway.\n * Caches the result for 5 minutes.\n *\n * @param url Override the trust policy URL (for testing or custom deployments)\n */\nexport async function fetchTrustPolicy(url?: string): Promise<TrustPolicy> {\n const now = Date.now();\n if (cachedPolicy && now - cacheTimestamp < CACHE_TTL_MS) {\n return cachedPolicy;\n }\n\n const res = await fetch(url ?? TRUST_POLICY_URL);\n if (!res.ok) {\n throw new Error(`Failed to fetch trust policy: ${res.status} ${res.statusText}`);\n }\n\n const policy: TrustPolicy = await res.json();\n\n if (!policy.version || !policy.chains || typeof policy.chains !== \"object\") {\n throw new Error(\"Invalid trust policy format\");\n }\n\n cachedPolicy = policy;\n cacheTimestamp = now;\n return policy;\n}\n\n/**\n * Extract the allowed contracts and schemas from a trust policy.\n * Returns all contracts and schemas across all chains.\n */\nexport function extractAllowlists(policy: TrustPolicy): {\n allowedContracts: string[];\n allowedSchemas: string[];\n} {\n const contracts: string[] = [];\n const schemas: string[] = [];\n\n for (const chain of Object.values(policy.chains)) {\n if (chain.easContract) contracts.push(chain.easContract);\n if (chain.schemas) schemas.push(...chain.schemas);\n }\n\n return {\n allowedContracts: [...new Set(contracts)],\n allowedSchemas: [...new Set(schemas)],\n };\n}\n","/**\n * Host-side signing bridge for OMATrust widget iframes.\n *\n * Handles the postMessage protocol between a host page and an embedded\n * OMATrust widget. Validates incoming EAS signing requests against the\n * OMA3 trust policy before forwarding to the host's wallet.\n *\n * The bridge resolves the iframe element lazily by ID when messages arrive,\n * avoiding React ref timing issues with conditionally rendered iframes.\n *\n * Usage:\n * import { createSigningBridge } from \"@oma3/omatrust/widgets\";\n *\n * const bridge = await createSigningBridge({\n * iframeId: \"omatrust-widget\",\n * signTypedData: async (domain, types, message) => {\n * return await signer.signTypedData(domain, types, message);\n * },\n * });\n *\n * bridge.destroy();\n */\n\nimport {\n OMATRUST_READY,\n OMATRUST_HOST_READY,\n OMATRUST_SIGN_TYPED_DATA,\n OMATRUST_SIGNATURE,\n OMATRUST_SIGNATURE_ERROR,\n} from \"./protocol\";\nimport { fetchTrustPolicy, extractAllowlists, TRUST_POLICY_URL } from \"./trust-policy\";\n\nexport type SigningBridgeOptions = {\n /**\n * The ID of the iframe element containing the widget.\n * The bridge looks up the element by ID when messages arrive,\n * so the iframe doesn't need to exist when the bridge is created.\n */\n iframeId: string;\n\n /**\n * Callback to sign EIP-712 typed data using the host's wallet.\n * Must return the hex-encoded signature string.\n */\n signTypedData: (\n domain: Record<string, unknown>,\n types: Record<string, unknown>,\n message: Record<string, unknown>\n ) => Promise<string>;\n\n /**\n * Override the allowed widget origin for local development.\n * In production, the origin is derived from the trust policy domain\n * (*.omatrust.org) plus any widgetOrigins in the policy.\n * Only set this for local dev (e.g., \"http://localhost:3000\").\n */\n devOriginOverride?: string;\n};\n\nexport type SigningBridge = {\n /** Remove all event listeners and stop the bridge. */\n destroy: () => void;\n};\n\n// ---------------------------------------------------------------------------\n// Origin resolution\n// ---------------------------------------------------------------------------\n\nfunction getTrustedBaseDomain(): string {\n try {\n const hostname = new URL(TRUST_POLICY_URL).hostname;\n const parts = hostname.split(\".\");\n return parts.length >= 2 ? parts.slice(-2).join(\".\") : hostname;\n } catch {\n return \"omatrust.org\";\n }\n}\n\nfunction isOriginTrusted(\n messageOrigin: string,\n baseDomain: string,\n policyOrigins: string[],\n devOverride?: string\n): boolean {\n if (devOverride && messageOrigin === devOverride) return true;\n\n try {\n const hostname = new URL(messageOrigin).hostname;\n if (hostname === baseDomain || hostname.endsWith(`.${baseDomain}`)) return true;\n } catch {\n // Invalid origin\n }\n\n if (policyOrigins.includes(messageOrigin)) return true;\n\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// EAS request validation\n// ---------------------------------------------------------------------------\n\nconst HEX_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;\nconst BYTES32_RE = /^0x[a-fA-F0-9]{64}$/;\n\ntype ValidationResult =\n | { valid: true }\n | { valid: false; reason: string };\n\nfunction validateEasSigningRequest(\n data: Record<string, unknown>,\n allowedSchemas: string[],\n allowedContracts: string[]\n): ValidationResult {\n const { id, domain, types, message } = data;\n\n if (!id || typeof id !== \"string\") {\n return { valid: false, reason: \"Missing or invalid request id\" };\n }\n if (!domain || typeof domain !== \"object\") {\n return { valid: false, reason: \"Missing domain object\" };\n }\n\n const d = domain as Record<string, unknown>;\n\n if (d.name !== \"EAS\") {\n return { valid: false, reason: `Unexpected domain name: \"${d.name}\" (expected \"EAS\")` };\n }\n if (d.version !== \"1.4.0\") {\n return { valid: false, reason: `Unexpected domain version: \"${d.version}\" (expected \"1.4.0\")` };\n }\n const chainId = Number(d.chainId);\n if (!Number.isInteger(chainId) || chainId <= 0) {\n return { valid: false, reason: `Invalid domain chainId: ${d.chainId}` };\n }\n if (typeof d.verifyingContract !== \"string\" || !HEX_ADDRESS_RE.test(d.verifyingContract)) {\n return { valid: false, reason: `Invalid verifyingContract: ${d.verifyingContract}` };\n }\n\n const contractLower = (d.verifyingContract as string).toLowerCase();\n if (!allowedContracts.some(c => c.toLowerCase() === contractLower)) {\n return { valid: false, reason: `Contract ${d.verifyingContract} is not in the OMA3 trust policy` };\n }\n\n if (!types || typeof types !== \"object\") {\n return { valid: false, reason: \"Missing types object\" };\n }\n if (!message || typeof message !== \"object\") {\n return { valid: false, reason: \"Missing message object\" };\n }\n\n const m = message as Record<string, unknown>;\n\n if (typeof m.schema !== \"string\" || !BYTES32_RE.test(m.schema)) {\n return { valid: false, reason: `Invalid schema UID: ${m.schema}` };\n }\n\n const schemaLower = m.schema.toLowerCase();\n if (!allowedSchemas.some(s => s.toLowerCase() === schemaLower)) {\n return { valid: false, reason: `Schema ${m.schema} is not in the OMA3 trust policy` };\n }\n\n if (typeof m.attester !== \"string\" || !HEX_ADDRESS_RE.test(m.attester)) {\n return { valid: false, reason: `Invalid attester address: ${m.attester}` };\n }\n\n const deadline = Number(m.deadline);\n if (!Number.isFinite(deadline) || deadline <= 0) {\n return { valid: false, reason: `Invalid deadline: ${m.deadline}` };\n }\n const now = Math.floor(Date.now() / 1000);\n if (deadline <= now) {\n return { valid: false, reason: `Deadline has passed: ${deadline} <= ${now}` };\n }\n\n return { valid: true };\n}\n\n// ---------------------------------------------------------------------------\n// Bridge implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Create a signing bridge between the host page and an OMATrust widget iframe.\n *\n * The bridge resolves the iframe element by ID when messages arrive, not at\n * creation time. This avoids React ref timing issues — the bridge can be\n * created before the iframe is in the DOM.\n *\n * Fetches the OMA3 trust policy on creation. Fails closed if unavailable.\n */\nexport async function createSigningBridge(options: SigningBridgeOptions): Promise<SigningBridge> {\n const { iframeId, signTypedData, devOriginOverride } = options;\n\n // Fetch the trust policy — fail closed if unavailable\n const policy = await fetchTrustPolicy();\n const { allowedContracts, allowedSchemas } = extractAllowlists(policy);\n\n if (allowedContracts.length === 0 || allowedSchemas.length === 0) {\n throw new Error(\"Trust policy contains no allowed contracts or schemas\");\n }\n\n const baseDomain = getTrustedBaseDomain();\n const policyOrigins = policy.widgetOrigins ?? [];\n\n async function handleMessage(event: MessageEvent) {\n const data = event.data;\n if (!data || typeof data !== \"object\" || typeof data.type !== \"string\") return;\n if (!String(data.type).startsWith(\"omatrust:\")) return;\n\n // Origin check\n if (!isOriginTrusted(event.origin, baseDomain, policyOrigins, devOriginOverride)) {\n return;\n }\n\n // Resolve the iframe element lazily by ID.\n // This works even if the iframe was mounted after the bridge was created.\n const iframe = document.getElementById(iframeId) as HTMLIFrameElement | null;\n if (!iframe) return;\n\n // Source check — must come from this specific iframe\n if (event.source !== iframe.contentWindow) {\n return;\n }\n\n const source = event.source as WindowProxy;\n\n // Determine reply origin from the iframe's current src\n const replyOrigin = devOriginOverride ?? (() => {\n try { return new URL(iframe.src).origin; }\n catch { return \"*\"; }\n })();\n\n function reply(msg: Record<string, unknown>) {\n source.postMessage(msg, replyOrigin);\n }\n\n // Handshake\n if (data.type === OMATRUST_READY) {\n reply({ type: OMATRUST_HOST_READY });\n return;\n }\n\n // Signing request\n if (data.type === OMATRUST_SIGN_TYPED_DATA) {\n const { id, domain, types, message } = data;\n\n const validation = validateEasSigningRequest(data, allowedSchemas, allowedContracts);\n if (!validation.valid) {\n reply({\n type: OMATRUST_SIGNATURE_ERROR,\n id: id ?? \"unknown\",\n error: `Signing request rejected: ${validation.reason}`,\n });\n return;\n }\n\n try {\n const signature = await signTypedData(domain, types, message);\n reply({ type: OMATRUST_SIGNATURE, id, signature });\n } catch (err) {\n const error = err instanceof Error ? err.message : \"Signing failed\";\n reply({ type: OMATRUST_SIGNATURE_ERROR, id, error });\n }\n }\n }\n\n window.addEventListener(\"message\", handleMessage);\n\n return {\n destroy() {\n window.removeEventListener(\"message\", handleMessage);\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/widgets/protocol.ts","../../src/shared/errors.ts","../../src/shared/trust-anchors.ts","../../src/widgets/bridge.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * postMessage protocol constants and types for the OMATrust widget bridge.\n *\n * Widget (iframe) → Host:\n * omatrust:ready — widget loaded, requesting handshake\n * omatrust:signTypedData — widget requests EIP-712 signature\n *\n * Host → Widget (iframe):\n * omatrust:hostReady — host acknowledges the widget\n * omatrust:signature — host returns a signature\n * omatrust:signatureError — host reports a signing failure\n */\n\nexport const OMATRUST_READY = \"omatrust:ready\" as const;\nexport const OMATRUST_HOST_READY = \"omatrust:hostReady\" as const;\nexport const OMATRUST_SIGN_TYPED_DATA = \"omatrust:signTypedData\" as const;\nexport const OMATRUST_SIGNATURE = \"omatrust:signature\" as const;\nexport const OMATRUST_SIGNATURE_ERROR = \"omatrust:signatureError\" as const;\n\nexport type OmaTrustReadyMessage = {\n type: typeof OMATRUST_READY;\n};\n\nexport type OmaTrustHostReadyMessage = {\n type: typeof OMATRUST_HOST_READY;\n};\n\nexport type OmaTrustSignTypedDataMessage = {\n type: typeof OMATRUST_SIGN_TYPED_DATA;\n id: string;\n domain: Record<string, unknown>;\n types: Record<string, unknown>;\n message: Record<string, unknown>;\n};\n\nexport type OmaTrustSignatureMessage = {\n type: typeof OMATRUST_SIGNATURE;\n id: string;\n signature: string;\n};\n\nexport type OmaTrustSignatureErrorMessage = {\n type: typeof OMATRUST_SIGNATURE_ERROR;\n id: string;\n error: string;\n};\n\nexport type OmaTrustMessage =\n | OmaTrustReadyMessage\n | OmaTrustHostReadyMessage\n | OmaTrustSignTypedDataMessage\n | OmaTrustSignatureMessage\n | OmaTrustSignatureErrorMessage;\n","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","/**\n * Trust anchors: fetches the OMA3 allowlist of EAS contracts and schemas.\n *\n * Used by the widget signing bridge for request validation and by the\n * reputation module for chain/contract resolution.\n *\n * Chain keys use CAIP-2 identifiers (e.g., \"eip155:66238\").\n */\n\nimport { OmaTrustError } from \"./errors\";\n\nconst DEFAULT_TRUST_ANCHORS_URL = \"https://api.omatrust.org/v1/trust-anchors\";\n\nexport const TRUST_ANCHORS_URL = DEFAULT_TRUST_ANCHORS_URL;\n\nexport type ChainAnchors = {\n name: string;\n easContract: string;\n /** Schema name → schema UID mapping */\n schemas: Record<string, string>;\n};\n\nexport type ApprovedIssuer = {\n address: string;\n label: string;\n schemas: string[];\n};\n\nexport type TrustAnchors = {\n version: number;\n updatedAt: string;\n widgetOrigins?: string[];\n /** CAIP-2 chain identifier → chain-specific trust anchors */\n chains: Record<string, ChainAnchors>;\n registries?: Array<{\n type: \"approved-issuers\";\n issuers: ApprovedIssuer[];\n }>;\n};\n\nlet cachedAnchors: TrustAnchors | null = null;\nlet cacheTimestamp = 0;\nconst CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n/**\n * Fetch the trust anchors from the OMA3 API gateway.\n * Caches the result for 5 minutes.\n *\n * @param url Override the trust anchors URL (for testing or custom deployments)\n */\nexport async function fetchTrustAnchors(url?: string): Promise<TrustAnchors> {\n const now = Date.now();\n if (cachedAnchors && now - cacheTimestamp < CACHE_TTL_MS) {\n return cachedAnchors;\n }\n\n let res: Response;\n try {\n res = await fetch(url ?? TRUST_ANCHORS_URL);\n } catch (err) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch trust anchors\", { err });\n }\n\n if (!res.ok) {\n throw new OmaTrustError(\"NETWORK_ERROR\", `Failed to fetch trust anchors: ${res.status} ${res.statusText}`);\n }\n\n const anchors: TrustAnchors = await res.json();\n\n if (!anchors.version || !anchors.chains || typeof anchors.chains !== \"object\") {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid trust anchors format\");\n }\n\n cachedAnchors = anchors;\n cacheTimestamp = now;\n return anchors;\n}\n\n/**\n * Look up chain anchors by CAIP-2 identifier.\n * Throws UNSUPPORTED_CHAIN if the chain is not in the trust anchors.\n */\nexport function getChainAnchors(anchors: TrustAnchors, caip2: string): ChainAnchors {\n const chain = anchors.chains[caip2];\n if (!chain) {\n throw new OmaTrustError(\"UNSUPPORTED_CHAIN\", `Chain ${caip2} is not in the trust anchors`, {\n caip2,\n supportedChains: Object.keys(anchors.chains),\n });\n }\n return chain;\n}\n\n/**\n * Look up a schema UID by name for a given chain.\n * Throws UNSUPPORTED_CHAIN if the chain is not in the trust anchors.\n * Throws INVALID_INPUT if the schema is not deployed on this chain.\n */\nexport function getSchemaAnchor(anchors: TrustAnchors, caip2: string, schemaName: string): string {\n const chain = getChainAnchors(anchors, caip2);\n const uid = chain.schemas[schemaName];\n if (!uid) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Schema \"${schemaName}\" not found in trust anchors for chain ${caip2}`, {\n caip2,\n schemaName,\n availableSchemas: Object.keys(chain.schemas),\n });\n }\n return uid;\n}\n\n/**\n * Extract the allowed contracts and schema UIDs from trust anchors.\n * Returns all contracts and schema UIDs across all chains.\n */\nexport function extractAllowlists(anchors: TrustAnchors): {\n allowedContracts: string[];\n allowedSchemas: string[];\n} {\n const contracts: string[] = [];\n const schemas: string[] = [];\n\n for (const chain of Object.values(anchors.chains)) {\n if (chain.easContract) contracts.push(chain.easContract);\n if (chain.schemas && typeof chain.schemas === \"object\") {\n schemas.push(...Object.values(chain.schemas));\n }\n }\n\n return {\n allowedContracts: [...new Set(contracts)],\n allowedSchemas: [...new Set(schemas)],\n };\n}\n","/**\n * Host-side signing bridge for OMATrust widget iframes.\n *\n * Handles the postMessage protocol between a host page and an embedded\n * OMATrust widget. Validates incoming EAS signing requests against the\n * OMA3 trust anchors before forwarding to the host's wallet.\n *\n * The bridge resolves the iframe element lazily by ID when messages arrive,\n * avoiding React ref timing issues with conditionally rendered iframes.\n *\n * Usage:\n * import { createSigningBridge } from \"@oma3/omatrust/widgets\";\n *\n * const bridge = await createSigningBridge({\n * iframeId: \"omatrust-widget\",\n * signTypedData: async (domain, types, message) => {\n * return await signer.signTypedData(domain, types, message);\n * },\n * });\n *\n * bridge.destroy();\n */\n\nimport {\n OMATRUST_READY,\n OMATRUST_HOST_READY,\n OMATRUST_SIGN_TYPED_DATA,\n OMATRUST_SIGNATURE,\n OMATRUST_SIGNATURE_ERROR,\n} from \"./protocol\";\nimport { fetchTrustAnchors, extractAllowlists, TRUST_ANCHORS_URL } from \"../shared/trust-anchors\";\n\nexport type SigningBridgeOptions = {\n /**\n * The ID of the iframe element containing the widget.\n * The bridge looks up the element by ID when messages arrive,\n * so the iframe doesn't need to exist when the bridge is created.\n */\n iframeId: string;\n\n /**\n * Callback to sign EIP-712 typed data using the host's wallet.\n * Must return the hex-encoded signature string.\n */\n signTypedData: (\n domain: Record<string, unknown>,\n types: Record<string, unknown>,\n message: Record<string, unknown>\n ) => Promise<string>;\n\n /**\n * Override the allowed widget origin for local development.\n * In production, the origin is derived from the trust anchors domain\n * (*.omatrust.org) plus any widgetOrigins in the trust anchors.\n * Only set this for local dev (e.g., \"http://localhost:3000\").\n */\n devOriginOverride?: string;\n};\n\nexport type SigningBridge = {\n /** Remove all event listeners and stop the bridge. */\n destroy: () => void;\n};\n\n// ---------------------------------------------------------------------------\n// Origin resolution\n// ---------------------------------------------------------------------------\n\nfunction getTrustedBaseDomain(): string {\n try {\n const hostname = new URL(TRUST_ANCHORS_URL).hostname;\n const parts = hostname.split(\".\");\n return parts.length >= 2 ? parts.slice(-2).join(\".\") : hostname;\n } catch {\n return \"omatrust.org\";\n }\n}\n\nfunction isOriginTrusted(\n messageOrigin: string,\n baseDomain: string,\n policyOrigins: string[],\n devOverride?: string\n): boolean {\n if (devOverride && messageOrigin === devOverride) return true;\n\n try {\n const hostname = new URL(messageOrigin).hostname;\n if (hostname === baseDomain || hostname.endsWith(`.${baseDomain}`)) return true;\n } catch {\n // Invalid origin\n }\n\n if (policyOrigins.includes(messageOrigin)) return true;\n\n return false;\n}\n\n// ---------------------------------------------------------------------------\n// EAS request validation\n// ---------------------------------------------------------------------------\n\nconst HEX_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;\nconst BYTES32_RE = /^0x[a-fA-F0-9]{64}$/;\n\ntype ValidationResult =\n | { valid: true }\n | { valid: false; reason: string };\n\nfunction validateEasSigningRequest(\n data: Record<string, unknown>,\n allowedSchemas: string[],\n allowedContracts: string[]\n): ValidationResult {\n const { id, domain, types, message } = data;\n\n if (!id || typeof id !== \"string\") {\n return { valid: false, reason: \"Missing or invalid request id\" };\n }\n if (!domain || typeof domain !== \"object\") {\n return { valid: false, reason: \"Missing domain object\" };\n }\n\n const d = domain as Record<string, unknown>;\n\n if (d.name !== \"EAS\") {\n return { valid: false, reason: `Unexpected domain name: \"${d.name}\" (expected \"EAS\")` };\n }\n if (d.version !== \"1.4.0\") {\n return { valid: false, reason: `Unexpected domain version: \"${d.version}\" (expected \"1.4.0\")` };\n }\n const chainId = Number(d.chainId);\n if (!Number.isInteger(chainId) || chainId <= 0) {\n return { valid: false, reason: `Invalid domain chainId: ${d.chainId}` };\n }\n if (typeof d.verifyingContract !== \"string\" || !HEX_ADDRESS_RE.test(d.verifyingContract)) {\n return { valid: false, reason: `Invalid verifyingContract: ${d.verifyingContract}` };\n }\n\n const contractLower = (d.verifyingContract as string).toLowerCase();\n if (!allowedContracts.some(c => c.toLowerCase() === contractLower)) {\n return { valid: false, reason: `Contract ${d.verifyingContract} is not in the OMA3 trust anchors` };\n }\n\n if (!types || typeof types !== \"object\") {\n return { valid: false, reason: \"Missing types object\" };\n }\n if (!message || typeof message !== \"object\") {\n return { valid: false, reason: \"Missing message object\" };\n }\n\n const m = message as Record<string, unknown>;\n\n if (typeof m.schema !== \"string\" || !BYTES32_RE.test(m.schema)) {\n return { valid: false, reason: `Invalid schema UID: ${m.schema}` };\n }\n\n const schemaLower = m.schema.toLowerCase();\n if (!allowedSchemas.some(s => s.toLowerCase() === schemaLower)) {\n return { valid: false, reason: `Schema ${m.schema} is not in the OMA3 trust anchors` };\n }\n\n if (typeof m.attester !== \"string\" || !HEX_ADDRESS_RE.test(m.attester)) {\n return { valid: false, reason: `Invalid attester address: ${m.attester}` };\n }\n\n const deadline = Number(m.deadline);\n if (!Number.isFinite(deadline) || deadline <= 0) {\n return { valid: false, reason: `Invalid deadline: ${m.deadline}` };\n }\n const now = Math.floor(Date.now() / 1000);\n if (deadline <= now) {\n return { valid: false, reason: `Deadline has passed: ${deadline} <= ${now}` };\n }\n\n return { valid: true };\n}\n\n// ---------------------------------------------------------------------------\n// Bridge implementation\n// ---------------------------------------------------------------------------\n\n/**\n * Create a signing bridge between the host page and an OMATrust widget iframe.\n *\n * The bridge resolves the iframe element by ID when messages arrive, not at\n * creation time. This avoids React ref timing issues — the bridge can be\n * created before the iframe is in the DOM.\n *\n * Fetches the OMA3 trust anchors on creation. Fails closed if unavailable.\n */\nexport async function createSigningBridge(options: SigningBridgeOptions): Promise<SigningBridge> {\n const { iframeId, signTypedData, devOriginOverride } = options;\n\n // Fetch the trust anchors: fail closed if unavailable.\n const anchors = await fetchTrustAnchors();\n const { allowedContracts, allowedSchemas } = extractAllowlists(anchors);\n\n if (allowedContracts.length === 0 || allowedSchemas.length === 0) {\n throw new Error(\"Trust anchors contain no allowed contracts or schemas\");\n }\n\n const baseDomain = getTrustedBaseDomain();\n const anchorOrigins = anchors.widgetOrigins ?? [];\n\n async function handleMessage(event: MessageEvent) {\n const data = event.data;\n if (!data || typeof data !== \"object\" || typeof data.type !== \"string\") return;\n if (!String(data.type).startsWith(\"omatrust:\")) return;\n\n // Origin check\n if (!isOriginTrusted(event.origin, baseDomain, anchorOrigins, devOriginOverride)) {\n return;\n }\n\n // Resolve the iframe element lazily by ID.\n // This works even if the iframe was mounted after the bridge was created.\n const iframe = document.getElementById(iframeId) as HTMLIFrameElement | null;\n if (!iframe) return;\n\n // Source check — must come from this specific iframe\n if (event.source !== iframe.contentWindow) {\n return;\n }\n\n const source = event.source as WindowProxy;\n\n // Determine reply origin from the iframe's current src\n const replyOrigin = devOriginOverride ?? (() => {\n try { return new URL(iframe.src).origin; }\n catch { return \"*\"; }\n })();\n\n function reply(msg: Record<string, unknown>) {\n source.postMessage(msg, replyOrigin);\n }\n\n // Handshake\n if (data.type === OMATRUST_READY) {\n reply({ type: OMATRUST_HOST_READY });\n return;\n }\n\n // Signing request\n if (data.type === OMATRUST_SIGN_TYPED_DATA) {\n const { id, domain, types, message } = data;\n\n const validation = validateEasSigningRequest(data, allowedSchemas, allowedContracts);\n if (!validation.valid) {\n reply({\n type: OMATRUST_SIGNATURE_ERROR,\n id: id ?? \"unknown\",\n error: `Signing request rejected: ${validation.reason}`,\n });\n return;\n }\n\n try {\n const signature = await signTypedData(domain, types, message);\n reply({ type: OMATRUST_SIGNATURE, id, signature });\n } catch (err) {\n const error = err instanceof Error ? err.message : \"Signing failed\";\n reply({ type: OMATRUST_SIGNATURE_ERROR, id, error });\n }\n }\n }\n\n window.addEventListener(\"message\", handleMessage);\n\n return {\n destroy() {\n window.removeEventListener(\"message\", handleMessage);\n },\n };\n}\n"]}
|
package/dist/widgets/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles the postMessage protocol between a host page and an embedded
|
|
5
5
|
* OMATrust widget. Validates incoming EAS signing requests against the
|
|
6
|
-
* OMA3 trust
|
|
6
|
+
* OMA3 trust anchors before forwarding to the host's wallet.
|
|
7
7
|
*
|
|
8
8
|
* The bridge resolves the iframe element lazily by ID when messages arrive,
|
|
9
9
|
* avoiding React ref timing issues with conditionally rendered iframes.
|
|
@@ -34,8 +34,8 @@ type SigningBridgeOptions = {
|
|
|
34
34
|
signTypedData: (domain: Record<string, unknown>, types: Record<string, unknown>, message: Record<string, unknown>) => Promise<string>;
|
|
35
35
|
/**
|
|
36
36
|
* Override the allowed widget origin for local development.
|
|
37
|
-
* In production, the origin is derived from the trust
|
|
38
|
-
* (*.omatrust.org) plus any widgetOrigins in the
|
|
37
|
+
* In production, the origin is derived from the trust anchors domain
|
|
38
|
+
* (*.omatrust.org) plus any widgetOrigins in the trust anchors.
|
|
39
39
|
* Only set this for local dev (e.g., "http://localhost:3000").
|
|
40
40
|
*/
|
|
41
41
|
devOriginOverride?: string;
|
|
@@ -51,40 +51,64 @@ type SigningBridge = {
|
|
|
51
51
|
* creation time. This avoids React ref timing issues — the bridge can be
|
|
52
52
|
* created before the iframe is in the DOM.
|
|
53
53
|
*
|
|
54
|
-
* Fetches the OMA3 trust
|
|
54
|
+
* Fetches the OMA3 trust anchors on creation. Fails closed if unavailable.
|
|
55
55
|
*/
|
|
56
56
|
declare function createSigningBridge(options: SigningBridgeOptions): Promise<SigningBridge>;
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
* Trust
|
|
59
|
+
* Trust anchors: fetches the OMA3 allowlist of EAS contracts and schemas.
|
|
60
60
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
61
|
+
* Used by the widget signing bridge for request validation and by the
|
|
62
|
+
* reputation module for chain/contract resolution.
|
|
63
|
+
*
|
|
64
|
+
* Chain keys use CAIP-2 identifiers (e.g., "eip155:66238").
|
|
63
65
|
*/
|
|
64
|
-
declare const
|
|
65
|
-
type
|
|
66
|
+
declare const TRUST_ANCHORS_URL = "https://api.omatrust.org/v1/trust-anchors";
|
|
67
|
+
type ChainAnchors = {
|
|
66
68
|
name: string;
|
|
67
69
|
easContract: string;
|
|
70
|
+
/** Schema name → schema UID mapping */
|
|
71
|
+
schemas: Record<string, string>;
|
|
72
|
+
};
|
|
73
|
+
type ApprovedIssuer = {
|
|
74
|
+
address: string;
|
|
75
|
+
label: string;
|
|
68
76
|
schemas: string[];
|
|
69
77
|
};
|
|
70
|
-
type
|
|
78
|
+
type TrustAnchors = {
|
|
71
79
|
version: number;
|
|
72
80
|
updatedAt: string;
|
|
73
81
|
widgetOrigins?: string[];
|
|
74
|
-
|
|
82
|
+
/** CAIP-2 chain identifier → chain-specific trust anchors */
|
|
83
|
+
chains: Record<string, ChainAnchors>;
|
|
84
|
+
registries?: Array<{
|
|
85
|
+
type: "approved-issuers";
|
|
86
|
+
issuers: ApprovedIssuer[];
|
|
87
|
+
}>;
|
|
75
88
|
};
|
|
76
89
|
/**
|
|
77
|
-
* Fetch the trust
|
|
90
|
+
* Fetch the trust anchors from the OMA3 API gateway.
|
|
78
91
|
* Caches the result for 5 minutes.
|
|
79
92
|
*
|
|
80
|
-
* @param url Override the trust
|
|
93
|
+
* @param url Override the trust anchors URL (for testing or custom deployments)
|
|
94
|
+
*/
|
|
95
|
+
declare function fetchTrustAnchors(url?: string): Promise<TrustAnchors>;
|
|
96
|
+
/**
|
|
97
|
+
* Look up chain anchors by CAIP-2 identifier.
|
|
98
|
+
* Throws UNSUPPORTED_CHAIN if the chain is not in the trust anchors.
|
|
99
|
+
*/
|
|
100
|
+
declare function getChainAnchors(anchors: TrustAnchors, caip2: string): ChainAnchors;
|
|
101
|
+
/**
|
|
102
|
+
* Look up a schema UID by name for a given chain.
|
|
103
|
+
* Throws UNSUPPORTED_CHAIN if the chain is not in the trust anchors.
|
|
104
|
+
* Throws INVALID_INPUT if the schema is not deployed on this chain.
|
|
81
105
|
*/
|
|
82
|
-
declare function
|
|
106
|
+
declare function getSchemaAnchor(anchors: TrustAnchors, caip2: string, schemaName: string): string;
|
|
83
107
|
/**
|
|
84
|
-
* Extract the allowed contracts and
|
|
85
|
-
* Returns all contracts and
|
|
108
|
+
* Extract the allowed contracts and schema UIDs from trust anchors.
|
|
109
|
+
* Returns all contracts and schema UIDs across all chains.
|
|
86
110
|
*/
|
|
87
|
-
declare function extractAllowlists(
|
|
111
|
+
declare function extractAllowlists(anchors: TrustAnchors): {
|
|
88
112
|
allowedContracts: string[];
|
|
89
113
|
allowedSchemas: string[];
|
|
90
114
|
};
|
|
@@ -131,4 +155,4 @@ type OmaTrustSignatureErrorMessage = {
|
|
|
131
155
|
};
|
|
132
156
|
type OmaTrustMessage = OmaTrustReadyMessage | OmaTrustHostReadyMessage | OmaTrustSignTypedDataMessage | OmaTrustSignatureMessage | OmaTrustSignatureErrorMessage;
|
|
133
157
|
|
|
134
|
-
export { type
|
|
158
|
+
export { type ApprovedIssuer, type ChainAnchors, OMATRUST_HOST_READY, OMATRUST_READY, OMATRUST_SIGNATURE, OMATRUST_SIGNATURE_ERROR, OMATRUST_SIGN_TYPED_DATA, type OmaTrustHostReadyMessage, type OmaTrustMessage, type OmaTrustReadyMessage, type OmaTrustSignTypedDataMessage, type OmaTrustSignatureErrorMessage, type OmaTrustSignatureMessage, type SigningBridge, type SigningBridgeOptions, TRUST_ANCHORS_URL, type TrustAnchors, createSigningBridge, extractAllowlists, fetchTrustAnchors, getChainAnchors, getSchemaAnchor };
|