@ghostlytools/cli 1.3.7 → 1.3.8
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 +8 -5
- package/SKILL.md +2 -0
- package/dist/assets/{api-BL0vpWGN.js → api-CYG-sByy.js} +2 -2
- package/dist/assets/{api-DlxlF4jP.js → api-Q6QZ0oIy.js} +50 -24
- package/dist/assets/api-Q6QZ0oIy.js.map +1 -0
- package/dist/assets/{apiKit-BnpVuZrZ.js → apiKit-C9lLXQwt.js} +2 -2
- package/dist/assets/{apiKit-BnpVuZrZ.js.map → apiKit-C9lLXQwt.js.map} +1 -1
- package/dist/assets/{apps-B_6Q-Mq-.js → apps-Bs8xpLGv.js} +1 -1
- package/dist/assets/{apps-Bs6QYQjm.js → apps-tcynvhlC.js} +2 -2
- package/dist/assets/{apps-Bs6QYQjm.js.map → apps-tcynvhlC.js.map} +1 -1
- package/dist/assets/{arkade-DwgUNqCz.js → arkade-BgmB0fUk.js} +2 -2
- package/dist/assets/{arkade-DwgUNqCz.js.map → arkade-BgmB0fUk.js.map} +1 -1
- package/dist/assets/{backup-BqtsbjOT.js → backup-OlEHNkqQ.js} +1 -1
- package/dist/assets/{backup-DEe1NqKb.js → backup-XtMACsQ0.js} +4 -4
- package/dist/assets/{backup-DEe1NqKb.js.map → backup-XtMACsQ0.js.map} +1 -1
- package/dist/assets/buttons-BoGOYSHb.js +2 -0
- package/dist/assets/{buttons-D9NQ3kV0.js → buttons-mdl2Gol2.js} +3 -3
- package/dist/assets/{buttons-D9NQ3kV0.js.map → buttons-mdl2Gol2.js.map} +1 -1
- package/dist/assets/{envelope-WC8QWYIL.js → envelope-DHf3mrHv.js} +2 -2
- package/dist/assets/{envelope-WC8QWYIL.js.map → envelope-DHf3mrHv.js.map} +1 -1
- package/dist/assets/{groupFiles-BrCMSXxg.js → groupFiles-CqrujNN1.js} +3 -3
- package/dist/assets/{groupFiles-BrCMSXxg.js.map → groupFiles-CqrujNN1.js.map} +1 -1
- package/dist/assets/{host-H0IYKNoK.js → host-Mz74S9cM.js} +29 -9
- package/dist/assets/host-Mz74S9cM.js.map +1 -0
- package/dist/assets/{hyperdhtRelay-CEfwbaCO.js → hyperdhtRelay-BnqdXvmv.js} +2 -2
- package/dist/assets/{hyperdhtRelay-CEfwbaCO.js.map → hyperdhtRelay-BnqdXvmv.js.map} +1 -1
- package/dist/assets/{irohWeb-Bn-JA2kp.js → irohWeb-C8iKFl8d.js} +2 -2
- package/dist/assets/{irohWeb-Bn-JA2kp.js.map → irohWeb-C8iKFl8d.js.map} +1 -1
- package/dist/assets/{main-DiCC-Vjq.js → main-BXwlJall.js} +52 -27
- package/dist/assets/main-BXwlJall.js.map +1 -0
- package/dist/assets/{mainline-gU7pE7s2.js → mainline-CbrPHUrZ.js} +2 -2
- package/dist/assets/{mainline-gU7pE7s2.js.map → mainline-CbrPHUrZ.js.map} +1 -1
- package/dist/assets/{networkReason-Dl9JThBQ.js → networkReason-CrrB031Y.js} +2 -2
- package/dist/assets/{networkReason-Dl9JThBQ.js.map → networkReason-CrrB031Y.js.map} +1 -1
- package/dist/assets/{nwc-CKjZjg-q.js → nwc-Cu5zwrE8.js} +3 -3
- package/dist/assets/{nwc-CKjZjg-q.js.map → nwc-Cu5zwrE8.js.map} +1 -1
- package/dist/assets/{nwcProvider-GDrc0HM4.js → nwcProvider-BVVFfJM5.js} +2 -2
- package/dist/assets/{nwcProvider-GDrc0HM4.js.map → nwcProvider-BVVFfJM5.js.map} +1 -1
- package/dist/assets/{registry-JGOFtJDE.js → registry-BKm8N_TI.js} +3 -3
- package/dist/assets/{registry-JGOFtJDE.js.map → registry-BKm8N_TI.js.map} +1 -1
- package/dist/assets/{registry-Wk7ZHuwm.js → registry-CshC1EyV.js} +1 -1
- package/dist/assets/{resolve-CVpEbud3.js → resolve-DKGaPeMz.js} +2 -2
- package/dist/assets/{resolve-CVpEbud3.js.map → resolve-DKGaPeMz.js.map} +1 -1
- package/dist/assets/{server-CkYscxE3.js → server-CaDVxJKy.js} +17 -13
- package/dist/assets/{server-CkYscxE3.js.map → server-CaDVxJKy.js.map} +1 -1
- package/dist/assets/{src-gJqfoRKI.js → src-CVYir6mP.js} +127 -17
- package/dist/assets/src-CVYir6mP.js.map +1 -0
- package/dist/assets/{turnRefs-zUQbFkl3.js → turnRefs-BeWsTX0o.js} +2 -2
- package/dist/assets/{turnRefs-zUQbFkl3.js.map → turnRefs-BeWsTX0o.js.map} +1 -1
- package/dist/assets/{usdt-BkDMGqZa.js → usdt-C5Q0BWHr.js} +3 -3
- package/dist/assets/{usdt-BkDMGqZa.js.map → usdt-C5Q0BWHr.js.map} +1 -1
- package/dist/ghostly.mjs +1 -1
- package/package.json +1 -1
- package/dist/assets/api-DlxlF4jP.js.map +0 -1
- package/dist/assets/buttons-CB1opfZP.js +0 -2
- package/dist/assets/host-H0IYKNoK.js.map +0 -1
- package/dist/assets/main-DiCC-Vjq.js.map +0 -1
- package/dist/assets/src-gJqfoRKI.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as identityProvider, r as identityProviders, t as IDENTITY_PROVIDERS } from "./registry-
|
|
1
|
+
import { n as identityProvider, r as identityProviders, t as IDENTITY_PROVIDERS } from "./registry-BKm8N_TI.js";
|
|
2
2
|
export { IDENTITY_PROVIDERS, identityProvider, identityProviders };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ai as isPublicAddress, Dt as parseAtprotoDidDocument, Ei as dnsProofName, Fi as recordsName, Ii as txtValue, Li as wellKnownUrl, Mi as normalizeDomain, Ni as recordsFromTxt, Pi as recordsFromWellKnown, Ti as decodeDnsResponse, Tt as isAtprotoDid, ji as nip05RootKey, ki as encodeDnsQuery, qi as boundVerifiedIdentity, wi as DOMAIN_FILE_MAX_BYTES, wl as toBase64Url, xt as atprotoDidMethod } from "./src-
|
|
1
|
+
import { Ai as isPublicAddress, Dt as parseAtprotoDidDocument, Ei as dnsProofName, Fi as recordsName, Ii as txtValue, Li as wellKnownUrl, Mi as normalizeDomain, Ni as recordsFromTxt, Pi as recordsFromWellKnown, Ti as decodeDnsResponse, Tt as isAtprotoDid, ji as nip05RootKey, ki as encodeDnsQuery, qi as boundVerifiedIdentity, wi as DOMAIN_FILE_MAX_BYTES, wl as toBase64Url, xt as atprotoDidMethod } from "./src-CVYir6mP.js";
|
|
2
2
|
import { l as providerDescriptorProblems } from "./types-C4_KafL_.js";
|
|
3
3
|
//#region ../browser/src/shared/features.ts
|
|
4
4
|
/**
|
|
@@ -603,4 +603,4 @@ async function verifiedAtprotoHandle(doc, options) {
|
|
|
603
603
|
//#endregion
|
|
604
604
|
export { reserveAdapterIds as _, DomainCheckError as a, testBuild as b, assertPublicHost as c, ownDid as d, setOwnDidSource as f, registeredOnchainProviders as g, registeredLightningProviders as h, verifiedAtprotoHandle as i, chosenResolver as l, registeredIdentityProviders as m, resolveAtprotoDid as n, assertDomainRecord as o, onAdaptersChanged as p, resolveAtprotoHandle as r, assertNip05 as s, assertPublicServer as t, resolverById as u, boundedIdentityFetch as v, verifyIdentity as y };
|
|
605
605
|
|
|
606
|
-
//# sourceMappingURL=resolve-
|
|
606
|
+
//# sourceMappingURL=resolve-DKGaPeMz.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-CVpEbud3.js","names":[],"sources":["../../../browser/src/shared/features.ts","../../../browser/src/proofs/verify.ts","../../../browser/src/plugins/bundled.ts","../../../browser/src/plugins/registry.ts","../../../browser/src/proofs/ownDid.ts","../../../browser/src/proofs/domain.ts","../../../browser/src/proofs/atproto/resolve.ts"],"sourcesContent":["/** Release policy: external identity experiments are retained for future work,\n * but must not advertise capabilities, start network lookups, or expose cached\n * external profiles. This does not gate Ghostly participation authentication. */\nexport const EXTERNAL_IDENTITIES_ENABLED: boolean = false;\n\n/** Mini-apps (WISP 1200): `apps/1` on paired sessions and the engine's `app*` calls. On from release 1.2 (a version\n * before 1.2.0 is never cut with it on: `RELEASE_GUARDS` in tools/scripts/changes.mjs). Off, nothing is offered to\n * contacts and every call is refused; a host that runs no apps pins its engine off (`NodeOptions.apps`). */\nexport const APPS_ENABLED: boolean = true;\n\n/**\n * A build that may be put into test mode: a development build (`import.meta.env.DEV`, which vitest also sets) or the\n * e2e suite's build (`VITE_APPS_TEST`, fixed when the build is made, as the mini-app switch is). A release build is\n * neither: Vite folds this to `false` there, so the storage flags the test fakes answer to are ignored. The fakes\n * themselves are still in the bundle (the registries import them); plugins may still pass fakes to the registry.\n */\nexport const testBuild = (): boolean => { try { return !!import.meta.env?.DEV || import.meta.env?.VITE_APPS_TEST === \"1\"; } catch { return false; } };\n","import { boundVerifiedIdentity, IDENTITY_MAX_EVIDENCE, IDENTITY_MAX_VALIDITY, type IdentityStatement, type VerifiedIdentity } from \"@ghostly/core\";\nimport type { IdentityFetch, IdentityProofProvider, IdentitySigner, VerifyContext } from \"./contract\";\n\nconst DAY = 86_400;\n\n/**\n * The checks every proof goes through, whatever its provider: known provider, validity within the\n * provider's limit, bounded evidence, strict parsing, the provider's own check, and the category rule\n * (a self-custodied proof proves exactly the subject it names; an attested one says who attests it).\n * The engine verifies a contact's proof, and the person's own proof before saving it, only through this.\n */\nexport async function verifyIdentity(providers: readonly IdentityProofProvider[], statement: IdentityStatement, evidence: unknown, ctx: VerifyContext): Promise<VerifiedIdentity> {\n const { binding } = statement;\n const provider = providers.find(p => p.id === binding.provider);\n if (!provider) throw new Error(\"This app cannot verify this kind of identity\");\n if (binding.expiresAt - binding.issuedAt > Math.min(provider.validity.maxDays * DAY, IDENTITY_MAX_VALIDITY)) throw new Error(\"The proof lasts longer than this kind of identity allows\");\n if (JSON.stringify(evidence ?? null).length > IDENTITY_MAX_EVIDENCE) throw new Error(\"Evidence too large\");\n const parsed = provider.parseEvidence(evidence);\n const verified = boundVerifiedIdentity(await provider.verify(statement, parsed, ctx));\n if (provider.category === \"self-custodied\" && verified.subject !== binding.subject) throw new Error(\"The evidence is for another identity\");\n if (provider.category === \"provider-attested\" && !verified.attester) throw new Error(\"The evidence does not say who attests it\");\n return verified;\n}\n\n/** Problems with a provider's descriptor, empty when it is well-formed. The registry and the contract suite use it. */\nexport function descriptorProblems(p: IdentityProofProvider): string[] {\n const problems: string[] = [];\n if (!/^[a-z][a-z0-9-]{0,31}$/.test(p.id)) problems.push(\"id must match ^[a-z][a-z0-9-]{0,31}$\");\n if (!p.label?.trim()) problems.push(\"label is empty\");\n if (!p.description?.trim()) problems.push(\"description is empty\");\n if (!p.privacy?.trim()) problems.push(\"privacy is empty: say what verify contacts\");\n if (p.category !== \"self-custodied\" && p.category !== \"provider-attested\") problems.push(\"category is unknown\");\n if (!p.platforms.length) problems.push(\"no platforms\");\n const { defaultDays, maxDays } = p.validity;\n if (!(Number.isInteger(defaultDays) && Number.isInteger(maxDays) && defaultDays >= 1 && defaultDays <= maxDays && maxDays * DAY <= IDENTITY_MAX_VALIDITY)) problems.push(\"validity must be whole days, 1 ≤ default ≤ max ≤ 400\");\n if (p.recheck && !(Number.isInteger(p.recheck.afterSeconds) && p.recheck.afterSeconds >= 60)) problems.push(\"recheck.afterSeconds must be at least 60\");\n if (!p.signers.length) problems.push(\"no signers\");\n const ids = p.signers.map(s => s.id);\n if (new Set(ids).size !== ids.length) problems.push(\"signer ids are not unique\");\n for (const s of p.signers as readonly IdentitySigner<unknown>[]) {\n if (![\"in-app\", \"external-tool\", \"redirect\", \"publish\"].includes(s.kind)) problems.push(`signer ${s.id} has an unknown kind`);\n if (s.kind === \"in-app\" && typeof s.run !== \"function\") problems.push(`signer ${s.id} has no run()`);\n if (s.kind === \"external-tool\" && (typeof s.instructions !== \"function\" || typeof s.parse !== \"function\")) problems.push(`signer ${s.id} needs instructions() and parse()`);\n if (s.kind === \"redirect\" && typeof s.start !== \"function\") problems.push(`signer ${s.id} has no start()`);\n if (s.kind === \"publish\" && (typeof s.instructions !== \"function\" || typeof s.evidence !== \"function\")) problems.push(`signer ${s.id} needs instructions() and evidence()`);\n }\n return problems;\n}\n\n/** Signers of a provider that run on this platform and are available in this window. */\nexport function availableSigners<E>(p: IdentityProofProvider<E>, platform: IdentityProofProvider[\"platforms\"][number]): IdentitySigner<E>[] {\n return p.signers.filter(s => (s.platforms ?? p.platforms).includes(platform) && (s.available?.() ?? true));\n}\n\n/**\n * The engine's `ctx.fetch`: HTTPS GET only, no credentials or referrer, a time-out, a size cap,\n * redirects refused unless asked for.\n * `online` false refuses everything (the person turned the network off).\n */\nexport function boundedIdentityFetch(options: { online: () => boolean; timeoutMs?: number; fetcher?: typeof fetch } = { online: () => true }): IdentityFetch {\n return async (url, { headers, maxBytes = 64 * 1024, signal, redirect = \"error\" } = {}) => {\n if (!options.online()) throw new Error(\"Offline: this identity cannot be checked now\");\n const target = new URL(url);\n if (target.protocol !== \"https:\" || target.username || target.password) throw new Error(\"Identity checks use HTTPS only\");\n const timeout = AbortSignal.timeout(options.timeoutMs ?? 10_000);\n const response = await (options.fetcher ?? fetch)(target.href, {\n headers, signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n credentials: \"omit\", referrerPolicy: \"no-referrer\", cache: \"no-store\", redirect,\n });\n if (Number(response.headers.get(\"content-length\")) > maxBytes) throw new Error(\"Identity check response too large\");\n const reader = response.body?.getReader();\n const parts: Uint8Array[] = [];\n let length = 0;\n if (reader) {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n length += value.length;\n if (length > maxBytes) throw new Error(\"Identity check response too large\");\n parts.push(value);\n }\n } finally { await reader.cancel().catch(() => {}); }\n }\n const bytes = new Uint8Array(length);\n let offset = 0;\n for (const part of parts) { bytes.set(part, offset); offset += part.length; }\n return { status: response.status, contentType: response.headers.get(\"content-type\") ?? \"\", text: new TextDecoder().decode(bytes), bytes };\n };\n}\n","import type { GhostlyAdapterPlugin } from \"./registry\";\n\n/**\n * The adapter plugins compiled into this build. Empty unless the build lists some: `GHOSTLY_PLUGINS`\n * names their modules (comma-separated paths from the repository root, each default-exporting a\n * `GhostlyAdapterPlugin`), and the Vite plugin in `packages/browser/vite-plugin.ts` swaps this module\n * for one that imports them. Release builds never set it; the e2e build carries the SDK example.\n */\nexport const BUNDLED_PLUGINS: readonly GhostlyAdapterPlugin[] = [];\n","import type { LightningProviderDescriptor } from \"../engine/paymentAdapters/providers/lightning\";\nimport type { OnchainProviderDescriptor } from \"../engine/paymentAdapters/providers/onchain\";\nimport { providerDescriptorProblems, type ProviderDescriptor, type ProviderKind } from \"../engine/paymentAdapters/providers/types\";\nimport type { IdentityProofProvider } from \"../proofs/contract\";\nimport { descriptorProblems } from \"../proofs/verify\";\nimport { BUNDLED_PLUGINS } from \"./bundled\";\n\n/**\n * Adapters written outside the app: wallet sources (Lightning, on-chain) and identity-proof providers\n * that register here instead of being added to the built-in lists. A plugin is a plain object naming\n * its adapters; the registries (`providers/registry.ts`, `proofs/registry.ts`) list what is registered\n * after the built-ins and before the test fakes, and the same platform and mode rules apply to all.\n *\n * Two ways in:\n * - at build time: `GHOSTLY_PLUGINS` lists the modules and `bundled.ts` is swapped for them;\n * - at run time: code already running in the engine's realm calls `registerAdapters` before the\n * pickers are shown (or after: the engine re-reads the lists when something registers).\n *\n * Trust: a plugin runs with the app's privileges, in the app's own JavaScript realm. There is no\n * sandbox, no permission prompt and no store; whoever builds a plugin in, or loads one, trusts its\n * author with everything the app can do, keys and sats included. A manifest with permissions and an\n * isolated runtime are a later phase (docs/wisps/ADAPTER-ROADMAP.md, \"Plugins, apps, catalogs\").\n *\n * The state lives on `globalThis` under a well-known symbol, so a plugin bundled with its own copy of\n * the SDK (a second copy of this module) still registers into the same lists the app reads.\n */\n\n/** The generation of the adapter contracts. A plugin says which one it was written against. */\nexport const SDK_API = 1;\nexport const PLUGIN_ID = /^[a-z][a-z0-9-]{0,63}$/;\n\nexport interface GhostlyAdapterPlugin {\n /** Stable, unique among plugins: `^[a-z][a-z0-9-]{0,63}$`. */\n id: string;\n /** The plugin's own version, for people. */\n version?: string;\n /** The contract generation it was written against: `SDK_API`. Another one is refused. */\n sdk: number;\n lightning?: readonly LightningProviderDescriptor[];\n onchain?: readonly OnchainProviderDescriptor[];\n identities?: readonly IdentityProofProvider[];\n}\n\nexport type AdapterKind = ProviderKind | \"identity\";\n\ninterface Store {\n plugins: Map<string, GhostlyAdapterPlugin>;\n /** Ids the built-in registries own, per kind: a plugin cannot take one. */\n reserved: Record<AdapterKind, Set<string>>;\n listeners: Set<() => void>;\n seeded: boolean;\n}\n\nconst KEY = Symbol.for(\"ghostly.adapters/1\");\nfunction store(): Store {\n const g = globalThis as unknown as Record<symbol, Store | undefined>;\n return (g[KEY] ??= { plugins: new Map(), reserved: { lightning: new Set(), onchain: new Set(), identity: new Set() }, listeners: new Set(), seeded: false });\n}\n\nconst ids = (kind: AdapterKind, plugin: GhostlyAdapterPlugin): string[] => {\n // Not trusted to be well formed: pluginProblems reads it before saying what is wrong with it.\n const list: unknown = kind === \"identity\" ? plugin.identities : kind === \"lightning\" ? plugin.lightning : plugin.onchain;\n return Array.isArray(list) ? list.map((a: { id?: string } | null) => a?.id as string) : [];\n};\nconst KINDS: readonly AdapterKind[] = [\"lightning\", \"onchain\", \"identity\"];\n\n/** Problems with a plugin, empty when it can be registered. Does not look at what is already registered. */\nexport function pluginProblems(plugin: GhostlyAdapterPlugin): string[] {\n const problems: string[] = [];\n if (!plugin || typeof plugin !== \"object\") return [\"not a plugin object\"];\n if (!PLUGIN_ID.test(plugin.id ?? \"\")) problems.push(\"plugin id must match ^[a-z][a-z0-9-]{0,63}$\");\n if (plugin.sdk !== SDK_API) problems.push(`plugin was written for SDK API ${String(plugin.sdk)}; this app speaks ${SDK_API}`);\n if (plugin.version !== undefined && (typeof plugin.version !== \"string\" || plugin.version.length > 64)) problems.push(\"version must be a short string\");\n for (const kind of [\"lightning\", \"onchain\"] as const) {\n const list = plugin[kind];\n if (list === undefined) continue;\n if (!Array.isArray(list)) { problems.push(`${kind} must be a list of descriptors`); continue; }\n for (const d of list as ProviderDescriptor<unknown>[]) {\n if (!d || typeof d !== \"object\") { problems.push(`${kind} ${String(d)}: not a descriptor`); continue; }\n const own = providerDescriptorProblems(d);\n if (d?.kind && d.kind !== kind) own.push(`is listed under ${kind} but says kind ${String(d.kind)}`);\n problems.push(...own.map((p) => `${kind} ${String(d?.id)}: ${p}`));\n }\n }\n if (plugin.identities !== undefined) {\n if (!Array.isArray(plugin.identities)) problems.push(\"identities must be a list of providers\");\n else for (const p of plugin.identities) {\n if (!p || typeof p !== \"object\") problems.push(`identity ${String(p)}: not a provider`);\n else problems.push(...descriptorProblems(p).map((m) => `identity ${String(p.id)}: ${m}`));\n }\n }\n for (const kind of KINDS) {\n const list = ids(kind, plugin);\n if (new Set(list).size !== list.length) problems.push(`${kind} ids are not unique within the plugin`);\n }\n if (!KINDS.some((kind) => ids(kind, plugin).length)) problems.push(\"the plugin brings no adapter\");\n return problems;\n}\n\n/** The built-in registries say which ids are theirs. A plugin using one is refused. */\nexport function reserveAdapterIds(kind: AdapterKind, list: readonly string[]): void {\n const s = store();\n for (const id of list) s.reserved[kind].add(id);\n}\n\n/**\n * Registers a plugin's adapters. Throws, registering nothing, when the plugin is malformed, its id or\n * one of its adapters' ids is taken (by a built-in or by another plugin), or its contract generation\n * is another one. Returns the function that unregisters it.\n */\nexport function registerAdapters(plugin: GhostlyAdapterPlugin): () => void {\n const problems = pluginProblems(plugin);\n const s = store();\n if (!problems.length) {\n if (s.plugins.has(plugin.id)) problems.push(`a plugin with id ${plugin.id} is already registered`);\n for (const kind of KINDS) for (const id of ids(kind, plugin)) {\n if (s.reserved[kind].has(id)) problems.push(`${kind} ${id} is a built-in of this app`);\n for (const other of s.plugins.values()) if (ids(kind, other).includes(id)) problems.push(`${kind} ${id} is already registered by plugin ${other.id}`);\n }\n }\n if (problems.length) throw new Error(`Cannot register plugin ${String(plugin?.id)}: ${problems.join(\"; \")}`);\n s.plugins.set(plugin.id, plugin);\n notify(s);\n return () => { if (s.plugins.get(plugin.id) === plugin) { s.plugins.delete(plugin.id); notify(s); } };\n}\n\nfunction notify(s: Store) { for (const listener of s.listeners) { try { listener(); } catch { /* a listener's problem */ } } }\n\n/** Called when a plugin registers or unregisters: the engine re-reads the lists. */\nexport function onAdaptersChanged(listener: () => void): () => void {\n const s = store();\n s.listeners.add(listener);\n return () => { s.listeners.delete(listener); };\n}\n\n/** Every registered plugin, in registration order (bundled ones first). */\nexport function registeredPlugins(): readonly GhostlyAdapterPlugin[] { seed(); return [...store().plugins.values()]; }\nexport function registeredLightningProviders(): readonly LightningProviderDescriptor[] { return registeredPlugins().flatMap((p) => p.lightning ?? []); }\nexport function registeredOnchainProviders(): readonly OnchainProviderDescriptor[] { return registeredPlugins().flatMap((p) => p.onchain ?? []); }\nexport function registeredIdentityProviders(): readonly IdentityProofProvider[] { return registeredPlugins().flatMap((p) => p.identities ?? []); }\n\n/**\n * The plugins compiled into this build register once, when they are first asked for. A broken one is\n * reported and skipped rather than taking the app down with it; the e2e that expects it fails instead.\n */\nfunction seed() {\n const s = store();\n if (s.seeded) return;\n s.seeded = true;\n for (const plugin of BUNDLED_PLUGINS) {\n try { registerAdapters(plugin); }\n catch (error) { console.error(`[ghostly] a bundled adapter plugin was not loaded: ${error instanceof Error ? error.message : String(error)}`); }\n }\n}\n\n/** Tests only: forget every registration, including the bundled ones. */\nexport function resetAdapterRegistry(): void {\n const s = store();\n s.plugins.clear(); s.seeded = false;\n for (const kind of KINDS) s.reserved[kind].clear();\n notify(s);\n}\n","/**\n * The profile's own Ghostly did:dht, which the DID provider refuses as an external identity. The UI and the engine each\n * set where to read it. Here, not in the provider, so setting it does not load the providers.\n */\nlet source: () => string | undefined = () => undefined;\nexport function setOwnDidSource(read: () => string | undefined): void { source = read; }\nexport const ownDid = (): string | undefined => source();\n","import {\n DOMAIN_FILE_MAX_BYTES, decodeDnsResponse, dnsProofName, encodeDnsQuery, isPublicAddress, nip05RootKey, normalizeDomain,\n recordsFromTxt, recordsFromWellKnown, recordsName, toBase64Url, txtValue, wellKnownUrl,\n type DnsResponse, type DnsType, type DomainMethod, type DomainRecord,\n} from '@ghostly/core';\nimport type { IdentityFetch } from './contract';\n\n/**\n * Network side of domain proofs: DNS TXT through DNS over HTTPS and the\n * `/.well-known/` files, under strict limits. Nothing here trusts the prover:\n * the domain comes from the signed binding, the URLs are built here, every\n * answer is bounded and parsed strictly, and lookups are cached only briefly.\n *\n * What a check reveals, and to whom:\n * - DNS: the chosen resolver learns that this device looked up `_ghostly.<domain>`\n * (the next one in DOH_RESOLVERS too, when the chosen one gives no answer).\n * The domain's own servers see only the resolver.\n * - HTTPS / NIP-05: the resolver learns the domain (its addresses are looked up\n * first, to refuse private networks), and the domain's web server — run by\n * the person being checked — sees this device's IP address and when.\n */\n\nexport type DohResolverId = 'quad9' | 'cloudflare' | 'google';\nexport interface DohResolver { id: DohResolverId; name: string; url: string }\n/** Public resolvers that answer RFC 8484 wire-format GETs with CORS (checked 2026-09-23). */\nexport const DOH_RESOLVERS: readonly DohResolver[] = [\n { id: 'quad9', name: 'Quad9', url: 'https://dns.quad9.net/dns-query' },\n { id: 'cloudflare', name: 'Cloudflare', url: 'https://cloudflare-dns.com/dns-query' },\n { id: 'google', name: 'Google', url: 'https://dns.google/dns-query' },\n];\nexport const DEFAULT_RESOLVER: DohResolverId = 'quad9';\nexport const resolverById = (id: string | null | undefined): DohResolver =>\n DOH_RESOLVERS.find(r => r.id === id) ?? DOH_RESOLVERS.find(r => r.id === DEFAULT_RESOLVER)!;\n\n/** The person's resolver choice, per browser profile (UI and engine share the origin). */\nexport const RESOLVER_SETTING = 'ghostly-doh-resolver';\nexport function chosenResolver(): DohResolver {\n try { return resolverById(globalThis.localStorage?.getItem(RESOLVER_SETTING)); } catch { return resolverById(undefined); }\n}\nexport function chooseResolver(id: DohResolverId): void {\n try { globalThis.localStorage?.setItem(RESOLVER_SETTING, resolverById(id).id); } catch { /* not persisted: the default stays */ }\n}\n\nexport const DNS_MAX_BYTES = 16 * 1024;\n/**\n * Lookups are shared between checks for the DNS TTL, capped: never staler than the resolver itself would\n * be, so a re-check sees a removal as soon as DNS does. Files have no TTL and are only shared in flight.\n */\nconst CACHE_MAX_MS = 30_000, CACHE_FILE_MS = 0;\n\n/** The contract's `ctx.fetch`: HTTPS GET, no credentials, bounded, redirects refused unless asked, with raw bytes. */\nexport type DomainFetch = IdentityFetch;\n\nexport interface DomainLookupOptions {\n fetch: DomainFetch;\n resolver?: DohResolverId;\n signal?: AbortSignal;\n /** Milliseconds. */\n now?: () => number;\n}\n\n/** A check that did not confirm the record, with a message for people. */\nexport class DomainCheckError extends Error {}\n\n/** A resolver that gave no DNS answer at all: not reached, or it refused the request. The next one may answer. */\nclass ResolverUnavailable extends DomainCheckError {}\n\n/** One RFC 8484 GET to one resolver. The query has ID 0 and no client subnet, so it carries only the name. */\nasync function askResolver(resolver: DohResolver, name: string, type: DnsType, options: DomainLookupOptions): Promise<DnsResponse> {\n let response: Awaited<ReturnType<DomainFetch>>;\n try {\n response = await options.fetch(`${resolver.url}?dns=${toBase64Url(encodeDnsQuery(name, type))}`, {\n headers: { accept: 'application/dns-message' }, maxBytes: DNS_MAX_BYTES, signal: options.signal, redirect: 'error' });\n } catch (e) {\n throw /too large/i.test(String(e))\n ? new DomainCheckError(`${resolver.name} sent an answer that is too large`)\n : new ResolverUnavailable(`${resolver.name} could not be reached`);\n }\n if (response.status !== 200 || !/^application\\/dns-message\\b/i.test(response.contentType))\n throw new ResolverUnavailable(`${resolver.name} refused the lookup`);\n let answer: DnsResponse;\n try { answer = decodeDnsResponse(response.bytes, name, type); } catch { throw new DomainCheckError(`${resolver.name} sent an unusable answer`); }\n if (answer.rcode !== 0 && answer.rcode !== 3) throw new DomainCheckError(`${resolver.name} could not resolve ${name}`);\n return answer;\n}\n\n/**\n * A lookup through the chosen resolver, and through the others in turn (in list order) only when it gives no DNS\n * answer at all. Quad9, for one, cannot be read from WebKit (the Mac desktop app, Safari): its HTTP/3 answers carry\n * no CORS header. An answer, even \"no such name\" or a failure, is never asked again elsewhere. `resolver`: who answered.\n */\nexport async function dohQuery(name: string, type: DnsType, options: DomainLookupOptions): Promise<DnsResponse & { resolver: DohResolverId }> {\n const chosen = resolverById(options.resolver);\n let first: DomainCheckError | undefined;\n for (const resolver of [chosen, ...DOH_RESOLVERS.filter(r => r !== chosen)]) {\n try { return { ...await askResolver(resolver, name, type, options), resolver: resolver.id }; }\n catch (e) {\n if (!(e instanceof ResolverUnavailable) || options.signal?.aborted) throw e;\n first ??= e;\n }\n }\n throw first!;\n}\n\n/**\n * Refuses a domain whose addresses are not all public before its web server is\n * contacted, so a proof cannot make a contact's app probe their own network.\n * The browser resolves again when it fetches; a name that changes its answer in\n * between (rebinding) is not fully excluded by this check — see the draft.\n */\nexport async function assertPublicHost(domain: string, options: DomainLookupOptions): Promise<void> {\n const [v4, v6] = await Promise.all([dohQuery(domain, 'A', options), dohQuery(domain, 'AAAA', options)]);\n const addresses = [...v4.answers, ...v6.answers].map(a => a.data);\n if (!addresses.length) throw new DomainCheckError(`${domain} has no address`);\n if (!addresses.every(isPublicAddress)) throw new DomainCheckError(`${domain} points to a private network address, so it was not contacted`);\n}\n\n/** A well-known file: https only, no redirects, bounded. `undefined` when the server says it is not there. */\nexport async function fetchWellKnown(domain: string, method: 'https' | 'nip05', options: DomainLookupOptions): Promise<string | undefined> {\n await assertPublicHost(domain, options);\n const url = wellKnownUrl(domain, method);\n let response: Awaited<ReturnType<DomainFetch>>;\n try {\n response = await options.fetch(url, { headers: { accept: 'application/json' }, maxBytes: DOMAIN_FILE_MAX_BYTES, signal: options.signal, redirect: 'error' });\n } catch (e) {\n throw new DomainCheckError(/too large/i.test(String(e)) ? `${url} is too large`\n : `${domain} could not be reached. The file must be served at exactly this address, without a redirect, with the header Access-Control-Allow-Origin: *`);\n }\n if (response.status === 404 || response.status === 410) return;\n if (response.status >= 300 && response.status < 400) throw new DomainCheckError(`${domain} answered with a redirect; the file must be served at exactly ${url}`);\n if (response.status !== 200) throw new DomainCheckError(`${domain} answered ${response.status}`);\n try { return new TextDecoder('utf-8', { fatal: true }).decode(response.bytes); } catch { throw new DomainCheckError(`${url} is not text`); }\n}\n\nexport interface DomainLookup {\n domain: string;\n method: DomainMethod;\n /** DNS / HTTPS: the Ghostly records found. */\n records: DomainRecord[];\n /** NIP-05: the Nostr key named for the domain itself. */\n nostrKey?: string;\n /** A record or file exists at all (as opposed to nothing there). */\n found: boolean;\n /** The resolver reported DNSSEC validation of the TXT answer. */\n dnssec: boolean;\n resolver: DohResolverId;\n}\n\nasync function lookup(domain: string, method: DomainMethod, options: DomainLookupOptions): Promise<DomainLookup & { ttlMs: number }> {\n const resolver = resolverById(options.resolver).id;\n if (method === 'dns') {\n const answer = await dohQuery(dnsProofName(domain), 'TXT', options);\n const values: string[] = [];\n for (const record of answer.answers.slice(0, 32)) { try { values.push(txtValue(record.data)); } catch { /* not text: not ours */ } }\n const ttlMs = answer.answers.length ? Math.min(...answer.answers.map(a => a.ttl)) * 1000 : 0;\n return { domain, method, resolver: answer.resolver, records: recordsFromTxt(values), found: answer.answers.length > 0, dnssec: answer.authenticated, ttlMs };\n }\n const text = await fetchWellKnown(domain, method, options);\n const base = { domain, method, resolver, dnssec: false, records: [] as DomainRecord[], ttlMs: CACHE_FILE_MS };\n if (text === undefined) return { ...base, found: false };\n try {\n return method === 'nip05' ? { ...base, found: true, nostrKey: nip05RootKey(text) } : { ...base, found: true, records: recordsFromWellKnown(text) };\n } catch { throw new DomainCheckError(`${wellKnownUrl(domain, method)} is not a valid ${method === 'nip05' ? 'NIP-05' : 'Ghostly'} file`); }\n}\n\nconst cache = new Map<string, { until: number; result: Promise<DomainLookup & { ttlMs: number }> }>();\n/** Tests only. */\nexport function clearDomainCache(): void { cache.clear(); }\n\n/** What a domain publishes by one method. Concurrent and back-to-back checks share one lookup. */\nexport async function lookupDomain(domainInput: string, method: DomainMethod, options: DomainLookupOptions): Promise<DomainLookup> {\n const domain = normalizeDomain(domainInput), now = options.now ?? Date.now, resolver = resolverById(options.resolver).id;\n const id = `${resolver}|${method}|${domain}`;\n const hit = cache.get(id);\n if (hit && hit.until > now()) { const { ttlMs: _ttl, ...result } = await hit.result; return result; }\n const started = now();\n const entry = { until: started + CACHE_MAX_MS, result: lookup(domain, method, { ...options, resolver }) };\n cache.set(id, entry);\n if (cache.size > 128) cache.delete(cache.keys().next().value!);\n try {\n const { ttlMs, ...result } = await entry.result;\n entry.until = started + Math.min(CACHE_MAX_MS, ttlMs);\n return result;\n } catch (e) {\n if (cache.get(id) === entry) cache.delete(id);\n throw e;\n }\n}\n\n/** Throws unless `domain` publishes `record` by `method` (DNS or HTTPS). Returns what was found. */\nexport async function assertDomainRecord(domain: string, method: 'dns' | 'https', record: DomainRecord, options: DomainLookupOptions): Promise<DomainLookup> {\n const found = await lookupDomain(domain, method, options);\n if (recordsName(found.records, record)) return found;\n const where = method === 'dns' ? `The TXT record at ${dnsProofName(domain)}` : wellKnownUrl(domain);\n if (found.records.some(r => r.key === record.key)) throw new DomainCheckError(`${where} is for another proof of this key`);\n if (found.records.length) throw new DomainCheckError(`${where} names another Ghostly key: this proof was replaced or removed`);\n throw new DomainCheckError(method === 'dns'\n ? `No Ghostly TXT record at ${dnsProofName(domain)}${found.found ? '' : ' (DNS changes can take a few minutes)'}`\n : found.found ? `${wellKnownUrl(domain)} names no Ghostly proof` : `${wellKnownUrl(domain)} was not found`);\n}\n\n/** Throws unless the domain's NIP-05 root name is `nostrKey`. */\nexport async function assertNip05(domain: string, nostrKey: string, options: DomainLookupOptions): Promise<DomainLookup> {\n const found = await lookupDomain(domain, 'nip05', options);\n if (found.nostrKey === nostrKey) return found;\n const url = wellKnownUrl(domain, 'nip05');\n throw new DomainCheckError(!found.found ? `${url} was not found` : found.nostrKey\n ? `${url} names another Nostr key for ${domain}` : `${url} has no root name \"_\" for ${domain}`);\n}\n","import { atprotoDidMethod, isAtprotoDid, parseAtprotoDidDocument, txtValue, type AtprotoDidDocument } from \"@ghostly/core\";\nimport type { IdentityFetch } from \"../contract\";\nimport { assertPublicHost, dohQuery, type DohResolverId } from \"../domain\";\n\n/**\n * AT Protocol identity resolution, the network half: a DID to its document (the PLC directory for\n * did:plc, the host's `/.well-known/did.json` for did:web), and a handle to a DID (DNS TXT\n * `_atproto.<handle>` through the person's DNS-over-HTTPS resolver, then\n * `https://<handle>/.well-known/atproto-did`). Every request goes through the contract's bounded\n * fetch: HTTPS only, no redirects, a size cap, a time-out. URLs are built here from the DID or the\n * handle, never taken from a proof.\n */\n\nexport const PLC_DIRECTORY = \"https://plc.directory\";\nconst TEST_HOST = /^https:\\/\\/[a-z0-9-]+(\\.[a-z0-9-]+)*\\.test$/;\n/** DID documents are small; a large answer is not one. */\nexport const DID_DOCUMENT_MAX_BYTES = 32 * 1024;\nconst HANDLE_DID_MAX_BYTES = 2048;\n\n/**\n * The PLC directory. A build made for the e2e suite with VITE_ATPROTO_TEST_PLC may point it at a\n * `.test` host (a name reserved for testing); a release build always uses plc.directory.\n */\nexport function plcDirectory(): string {\n try {\n const value = import.meta.env?.VITE_ATPROTO_TEST_PLC as string | undefined;\n return value && TEST_HOST.test(value) ? value : PLC_DIRECTORY;\n } catch { return PLC_DIRECTORY; }\n}\n\nexport interface AtprotoResolveOptions {\n fetch: IdentityFetch;\n signal?: AbortSignal;\n /** The DoH resolver for handles (the person's choice, as for domains). */\n resolver?: DohResolverId;\n /** The PLC directory; plcDirectory() by default. */\n plc?: string;\n}\n\n/** Where a DID's document lives. */\nexport function didDocumentUrl(did: string, plc = plcDirectory()): string {\n const method = atprotoDidMethod(did);\n if (method === \"plc\") return `${plc}/${did}`;\n if (method === \"web\") return `https://${did.slice(\"did:web:\".length)}/.well-known/did.json`;\n throw new Error(\"Not an AT Protocol DID\");\n}\n\n/**\n * Refuses a host the account chose (a did:web host, the PDS its document names) that points to a private\n * network address: a contact's app never knocks on its own local network for someone else's proof.\n */\nexport async function assertPublicServer(host: string, options: AtprotoResolveOptions): Promise<void> {\n try { await assertPublicHost(host, { fetch: options.fetch, signal: options.signal, resolver: options.resolver }); }\n catch (e) { throw new Error(`The account's server ${host} was not contacted: ${e instanceof Error ? e.message : String(e)}`); } // eslint-disable-line preserve-caught-error -- The domain check's message says why; ES2020 has no Error.cause.\n}\n\n/** A DID's document, checked (parseAtprotoDidDocument). Throws a message people can read. */\nexport async function resolveAtprotoDid(did: string, options: AtprotoResolveOptions): Promise<AtprotoDidDocument> {\n const url = didDocumentUrl(did, options.plc);\n if (atprotoDidMethod(did) === \"web\") await assertPublicServer(did.slice(\"did:web:\".length), options);\n let response: Awaited<ReturnType<IdentityFetch>>;\n try {\n response = await options.fetch(url, { headers: { accept: \"application/did+ld+json, application/json\" }, maxBytes: DID_DOCUMENT_MAX_BYTES, signal: options.signal, redirect: \"error\" });\n } catch (e) {\n // eslint-disable-next-line preserve-caught-error -- A message people can act on; the library's error stays out of the UI (ES2020 has no Error.cause).\n throw new Error(/too large/i.test(String(e)) ? \"The account's DID document is too large\" : \"The account's DID could not be resolved\");\n }\n if (response.status === 404 || response.status === 410) throw new Error(\"The account's DID is not registered, or was deactivated\");\n if (response.status !== 200) throw new Error(\"The account's DID could not be resolved\");\n let doc: unknown;\n try { doc = JSON.parse(response.text); } catch { throw new Error(\"The account's DID document is malformed\"); }\n return parseAtprotoDidDocument(doc, did);\n}\n\n/**\n * The DID a handle points to, or null when it points nowhere (or to two different DIDs). DNS first,\n * then HTTPS, as the handle spec says. The HTTPS lookup first checks the handle's addresses are public,\n * so a handle cannot make a contact's app knock on its local network.\n */\nexport async function resolveAtprotoHandle(handle: string, options: AtprotoResolveOptions): Promise<string | null> {\n const lookup = { fetch: options.fetch, signal: options.signal, resolver: options.resolver };\n try {\n const answer = await dohQuery(`_atproto.${handle}`, \"TXT\", lookup);\n const dids = new Set<string>();\n for (const a of answer.answers) {\n if (a.type !== 16) continue;\n let text: string;\n try { text = txtValue(a.data); } catch { continue; }\n if (text.startsWith(\"did=\")) dids.add(text.slice(4));\n }\n if (dids.size > 1) return null;\n const [did] = dids;\n if (did) return isAtprotoDid(did) ? did : null;\n } catch { /* The resolver failed: try HTTPS. */ }\n try {\n await assertPublicHost(handle, lookup);\n const response = await options.fetch(`https://${handle}/.well-known/atproto-did`, { headers: { accept: \"text/plain\" }, maxBytes: HANDLE_DID_MAX_BYTES, signal: options.signal, redirect: \"error\" });\n if (response.status !== 200) return null;\n const did = response.text.trim();\n return isAtprotoDid(did) ? did : null;\n } catch { return null; }\n}\n\n/**\n * The handle to show for a DID: the one its document claims, and only if that handle resolves back to\n * the same DID. Otherwise nothing: the card shows the DID. Never throws.\n */\nexport async function verifiedAtprotoHandle(doc: AtprotoDidDocument, options: AtprotoResolveOptions): Promise<string | undefined> {\n if (!doc.handle) return undefined;\n try { return (await resolveAtprotoHandle(doc.handle, options)) === doc.did ? doc.handle : undefined; } catch { return undefined; }\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAa,kBAA2B;CAAE,IAAI;EAAE,OAAiC;CAAyC,QAAQ;EAAE,OAAO;CAAO;AAAE;;;ACbpJ,IAAM,MAAM;;;;;;;AAQZ,eAAsB,eAAe,WAA6C,WAA8B,UAAmB,KAA+C;CAChL,MAAM,EAAE,YAAY;CACpB,MAAM,WAAW,UAAU,MAAK,MAAK,EAAE,OAAO,QAAQ,QAAQ;CAC9D,IAAI,CAAC,UAAU,MAAM,IAAI,MAAM,8CAA8C;CAC7E,IAAI,QAAQ,YAAY,QAAQ,WAAW,KAAK,IAAI,SAAS,SAAS,UAAU,KAAA,MAA0B,GAAG,MAAM,IAAI,MAAM,0DAA0D;CACvL,IAAI,KAAK,UAAU,YAAY,IAAI,CAAC,CAAC,SAAA,OAAgC,MAAM,IAAI,MAAM,oBAAoB;CACzG,MAAM,SAAS,SAAS,cAAc,QAAQ;CAC9C,MAAM,WAAW,sBAAsB,MAAM,SAAS,OAAO,WAAW,QAAQ,GAAG,CAAC;CACpF,IAAI,SAAS,aAAa,oBAAoB,SAAS,YAAY,QAAQ,SAAS,MAAM,IAAI,MAAM,sCAAsC;CAC1I,IAAI,SAAS,aAAa,uBAAuB,CAAC,SAAS,UAAU,MAAM,IAAI,MAAM,0CAA0C;CAC/H,OAAO;AACT;;AAGA,SAAgB,mBAAmB,GAAoC;CACrE,MAAM,WAAqB,CAAC;CAC5B,IAAI,CAAC,yBAAyB,KAAK,EAAE,EAAE,GAAG,SAAS,KAAK,sCAAsC;CAC9F,IAAI,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,KAAK,gBAAgB;CACpD,IAAI,CAAC,EAAE,aAAa,KAAK,GAAG,SAAS,KAAK,sBAAsB;CAChE,IAAI,CAAC,EAAE,SAAS,KAAK,GAAG,SAAS,KAAK,4CAA4C;CAClF,IAAI,EAAE,aAAa,oBAAoB,EAAE,aAAa,qBAAqB,SAAS,KAAK,qBAAqB;CAC9G,IAAI,CAAC,EAAE,UAAU,QAAQ,SAAS,KAAK,cAAc;CACrD,MAAM,EAAE,aAAa,YAAY,EAAE;CACnC,IAAI,EAAE,OAAO,UAAU,WAAW,KAAK,OAAO,UAAU,OAAO,KAAK,eAAe,KAAK,eAAe,WAAW,UAAU,OAAA,SAA+B,SAAS,KAAK,sDAAsD;CAC/N,IAAI,EAAE,WAAW,EAAE,OAAO,UAAU,EAAE,QAAQ,YAAY,KAAK,EAAE,QAAQ,gBAAgB,KAAK,SAAS,KAAK,0CAA0C;CACtJ,IAAI,CAAC,EAAE,QAAQ,QAAQ,SAAS,KAAK,YAAY;CACjD,MAAM,MAAM,EAAE,QAAQ,KAAI,MAAK,EAAE,EAAE;CACnC,IAAI,IAAI,IAAI,GAAG,CAAC,CAAC,SAAS,IAAI,QAAQ,SAAS,KAAK,2BAA2B;CAC/E,KAAK,MAAM,KAAK,EAAE,SAA+C;EAC/D,IAAI,CAAC;GAAC;GAAU;GAAiB;GAAY;EAAS,CAAC,CAAC,SAAS,EAAE,IAAI,GAAG,SAAS,KAAK,UAAU,EAAE,GAAG,qBAAqB;EAC5H,IAAI,EAAE,SAAS,YAAY,OAAO,EAAE,QAAQ,YAAY,SAAS,KAAK,UAAU,EAAE,GAAG,cAAc;EACnG,IAAI,EAAE,SAAS,oBAAoB,OAAO,EAAE,iBAAiB,cAAc,OAAO,EAAE,UAAU,aAAa,SAAS,KAAK,UAAU,EAAE,GAAG,kCAAkC;EAC1K,IAAI,EAAE,SAAS,cAAc,OAAO,EAAE,UAAU,YAAY,SAAS,KAAK,UAAU,EAAE,GAAG,gBAAgB;EACzG,IAAI,EAAE,SAAS,cAAc,OAAO,EAAE,iBAAiB,cAAc,OAAO,EAAE,aAAa,aAAa,SAAS,KAAK,UAAU,EAAE,GAAG,qCAAqC;CAC5K;CACA,OAAO;AACT;;;;;;AAYA,SAAgB,qBAAqB,UAAiF,EAAE,cAAc,KAAK,GAAkB;CAC3J,OAAO,OAAO,KAAK,EAAE,SAAS,WAAW,OAAW,QAAQ,WAAW,YAAY,CAAC,MAAM;EACxF,IAAI,CAAC,QAAQ,OAAO,GAAG,MAAM,IAAI,MAAM,8CAA8C;EACrF,MAAM,SAAS,IAAI,IAAI,GAAG;EAC1B,IAAI,OAAO,aAAa,YAAY,OAAO,YAAY,OAAO,UAAU,MAAM,IAAI,MAAM,gCAAgC;EACxH,MAAM,UAAU,YAAY,QAAQ,QAAQ,aAAa,GAAM;EAC/D,MAAM,WAAW,OAAO,QAAQ,WAAW,MAAA,CAAO,OAAO,MAAM;GAC7D;GAAS,QAAQ,SAAS,YAAY,IAAI,CAAC,QAAQ,OAAO,CAAC,IAAI;GAC/D,aAAa;GAAQ,gBAAgB;GAAe,OAAO;GAAY;EACzE,CAAC;EACD,IAAI,OAAO,SAAS,QAAQ,IAAI,gBAAgB,CAAC,IAAI,UAAU,MAAM,IAAI,MAAM,mCAAmC;EAClH,MAAM,SAAS,SAAS,MAAM,UAAU;EACxC,MAAM,QAAsB,CAAC;EAC7B,IAAI,SAAS;EACb,IAAI,QACF,IAAI;GACF,SAAS;IACP,MAAM,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK;IAC1C,IAAI,MAAM;IACV,UAAU,MAAM;IAChB,IAAI,SAAS,UAAU,MAAM,IAAI,MAAM,mCAAmC;IAC1E,MAAM,KAAK,KAAK;GAClB;EACF,UAAU;GAAE,MAAM,OAAO,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC;EAAG;EAErD,MAAM,QAAQ,IAAI,WAAW,MAAM;EACnC,IAAI,SAAS;EACb,KAAK,MAAM,QAAQ,OAAO;GAAE,MAAM,IAAI,MAAM,MAAM;GAAG,UAAU,KAAK;EAAQ;EAC5E,OAAO;GAAE,QAAQ,SAAS;GAAQ,aAAa,SAAS,QAAQ,IAAI,cAAc,KAAK;GAAI,MAAM,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK;GAAG;EAAM;CAC1I;AACF;;;;;;;;;ACjFA,IAAa,kBAAmD,CAAC;ACqBjE,IAAa,YAAY;AAwBzB,IAAM,MAAM,OAAO,IAAI,oBAAoB;AAC3C,SAAS,QAAe;CACtB,MAAM,IAAI;CACV,OAAQ,EAAE,SAAS;EAAE,yBAAS,IAAI,IAAI;EAAG,UAAU;GAAE,2BAAW,IAAI,IAAI;GAAG,yBAAS,IAAI,IAAI;GAAG,0BAAU,IAAI,IAAI;EAAE;EAAG,2BAAW,IAAI,IAAI;EAAG,QAAQ;CAAM;AAC5J;AAEA,IAAM,OAAO,MAAmB,WAA2C;CAEzE,MAAM,OAAgB,SAAS,aAAa,OAAO,aAAa,SAAS,cAAc,OAAO,YAAY,OAAO;CACjH,OAAO,MAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,MAA8B,GAAG,EAAY,IAAI,CAAC;AAC3F;AACA,IAAM,QAAgC;CAAC;CAAa;CAAW;AAAU;;AAGzE,SAAgB,eAAe,QAAwC;CACrE,MAAM,WAAqB,CAAC;CAC5B,IAAI,CAAC,UAAU,OAAO,WAAW,UAAU,OAAO,CAAC,qBAAqB;CACxE,IAAI,CAAC,UAAU,KAAK,OAAO,MAAM,EAAE,GAAG,SAAS,KAAK,6CAA6C;CACjG,IAAI,OAAO,QAAA,GAAiB,SAAS,KAAK,kCAAkC,OAAO,OAAO,GAAG,EAAE,oBAA6B;CAC5H,IAAI,OAAO,YAAY,KAAA,MAAc,OAAO,OAAO,YAAY,YAAY,OAAO,QAAQ,SAAS,KAAK,SAAS,KAAK,gCAAgC;CACtJ,KAAK,MAAM,QAAQ,CAAC,aAAa,SAAS,GAAY;EACpD,MAAM,OAAO,OAAO;EACpB,IAAI,SAAS,KAAA,GAAW;EACxB,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;GAAE,SAAS,KAAK,GAAG,KAAK,+BAA+B;GAAG;EAAU;EAC9F,KAAK,MAAM,KAAK,MAAuC;GACrD,IAAI,CAAC,KAAK,OAAO,MAAM,UAAU;IAAE,SAAS,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC,EAAE,mBAAmB;IAAG;GAAU;GACtG,MAAM,MAAM,2BAA2B,CAAC;GACxC,IAAI,GAAG,QAAQ,EAAE,SAAS,MAAM,IAAI,KAAK,mBAAmB,KAAK,iBAAiB,OAAO,EAAE,IAAI,GAAG;GAClG,SAAS,KAAK,GAAG,IAAI,KAAK,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,EAAE,EAAE,IAAI,GAAG,CAAC;EACnE;CACF;CACA,IAAI,OAAO,eAAe,KAAA,GAAW;EACnC,IAAI,CAAC,MAAM,QAAQ,OAAO,UAAU,GAAG,SAAS,KAAK,wCAAwC;OACxF,KAAK,MAAM,KAAK,OAAO,YAC1B,IAAI,CAAC,KAAK,OAAO,MAAM,UAAU,SAAS,KAAK,YAAY,OAAO,CAAC,EAAE,iBAAiB;OACjF,SAAS,KAAK,GAAG,mBAAmB,CAAC,CAAC,CAAC,KAAK,MAAM,YAAY,OAAO,EAAE,EAAE,EAAE,IAAI,GAAG,CAAC;CAE5F;CACA,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,IAAI,MAAM,MAAM;EAC7B,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,SAAS,KAAK,QAAQ,SAAS,KAAK,GAAG,KAAK,sCAAsC;CACtG;CACA,IAAI,CAAC,MAAM,MAAM,SAAS,IAAI,MAAM,MAAM,CAAC,CAAC,MAAM,GAAG,SAAS,KAAK,8BAA8B;CACjG,OAAO;AACT;;AAGA,SAAgB,kBAAkB,MAAmB,MAA+B;CAClF,MAAM,IAAI,MAAM;CAChB,KAAK,MAAM,MAAM,MAAM,EAAE,SAAS,KAAK,CAAC,IAAI,EAAE;AAChD;;;;;;AAOA,SAAgB,iBAAiB,QAA0C;CACzE,MAAM,WAAW,eAAe,MAAM;CACtC,MAAM,IAAI,MAAM;CAChB,IAAI,CAAC,SAAS,QAAQ;EACpB,IAAI,EAAE,QAAQ,IAAI,OAAO,EAAE,GAAG,SAAS,KAAK,oBAAoB,OAAO,GAAG,uBAAuB;EACjG,KAAK,MAAM,QAAQ,OAAO,KAAK,MAAM,MAAM,IAAI,MAAM,MAAM,GAAG;GAC5D,IAAI,EAAE,SAAS,KAAK,CAAC,IAAI,EAAE,GAAG,SAAS,KAAK,GAAG,KAAK,GAAG,GAAG,2BAA2B;GACrF,KAAK,MAAM,SAAS,EAAE,QAAQ,OAAO,GAAG,IAAI,IAAI,MAAM,KAAK,CAAC,CAAC,SAAS,EAAE,GAAG,SAAS,KAAK,GAAG,KAAK,GAAG,GAAG,mCAAmC,MAAM,IAAI;EACtJ;CACF;CACA,IAAI,SAAS,QAAQ,MAAM,IAAI,MAAM,0BAA0B,OAAO,QAAQ,EAAE,EAAE,IAAI,SAAS,KAAK,IAAI,GAAG;CAC3G,EAAE,QAAQ,IAAI,OAAO,IAAI,MAAM;CAC/B,OAAO,CAAC;CACR,aAAa;EAAE,IAAI,EAAE,QAAQ,IAAI,OAAO,EAAE,MAAM,QAAQ;GAAE,EAAE,QAAQ,OAAO,OAAO,EAAE;GAAG,OAAO,CAAC;EAAG;CAAE;AACtG;AAEA,SAAS,OAAO,GAAU;CAAE,KAAK,MAAM,YAAY,EAAE,WAAa,IAAI;EAAE,SAAS;CAAG,QAAQ,CAA6B;AAAI;;AAG7H,SAAgB,kBAAkB,UAAkC;CAClE,MAAM,IAAI,MAAM;CAChB,EAAE,UAAU,IAAI,QAAQ;CACxB,aAAa;EAAE,EAAE,UAAU,OAAO,QAAQ;CAAG;AAC/C;;AAGA,SAAgB,oBAAqD;CAAE,KAAK;CAAG,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC,QAAQ,OAAO,CAAC;AAAG;AACrH,SAAgB,+BAAuE;CAAE,OAAO,kBAAkB,CAAC,CAAC,SAAS,MAAM,EAAE,aAAa,CAAC,CAAC;AAAG;AACvJ,SAAgB,6BAAmE;CAAE,OAAO,kBAAkB,CAAC,CAAC,SAAS,MAAM,EAAE,WAAW,CAAC,CAAC;AAAG;AACjJ,SAAgB,8BAAgE;CAAE,OAAO,kBAAkB,CAAC,CAAC,SAAS,MAAM,EAAE,cAAc,CAAC,CAAC;AAAG;;;;;AAMjJ,SAAS,OAAO;CACd,MAAM,IAAI,MAAM;CAChB,IAAI,EAAE,QAAQ;CACd,EAAE,SAAS;CACX,KAAK,MAAM,UAAU,iBACnB,IAAI;EAAE,iBAAiB,MAAM;CAAG,SACzB,OAAO;EAAE,QAAQ,MAAM,sDAAsD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAAG;CAAG;AAEnJ;;;;;;;ACrJA,IAAI,eAAyC,KAAA;AAC7C,SAAgB,gBAAgB,MAAsC;CAAE,SAAS;AAAM;AACvF,IAAa,eAAmC,OAAO;;;;ACmBvD,IAAa,gBAAwC;CACnD;EAAE,IAAI;EAAS,MAAM;EAAS,KAAK;CAAkC;CACrE;EAAE,IAAI;EAAc,MAAM;EAAc,KAAK;CAAuC;CACpF;EAAE,IAAI;EAAU,MAAM;EAAU,KAAK;CAA+B;AACtE;AAEA,IAAa,gBAAgB,OAC3B,cAAc,MAAK,MAAK,EAAE,OAAO,EAAE,KAAK,cAAc,MAAK,MAAK,EAAE,OAAA,OAAuB;;AAG3F,IAAa,mBAAmB;AAChC,SAAgB,iBAA8B;CAC5C,IAAI;EAAE,OAAO,aAAa,WAAW,cAAc,QAAQ,gBAAgB,CAAC;CAAG,QAAQ;EAAE,OAAO,aAAa,KAAA,CAAS;CAAG;AAC3H;AAKA,IAAa,gBAAgB;;;;;AAK7B,IAAM,eAAe;AAAQ,IAAA,gBAAgB;;AAc7C,IAAa,mBAAb,cAAsC,MAAM,CAAC;;AAG7C,IAAM,sBAAN,cAAkC,iBAAiB,CAAC;;AAGpD,eAAe,YAAY,UAAuB,MAAc,MAAe,SAAoD;CACjI,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,QAAQ,MAAM,GAAG,SAAS,IAAI,OAAO,YAAY,eAAe,MAAM,IAAI,CAAC,KAAK;GAC/F,SAAS,EAAE,QAAQ,0BAA0B;GAAG,UAAU;GAAe,QAAQ,QAAQ;GAAQ,UAAU;EAAQ,CAAC;CACxH,SAAS,GAAG;EACV,MAAM,aAAa,KAAK,OAAO,CAAC,CAAC,IAC7B,IAAI,iBAAiB,GAAG,SAAS,KAAK,kCAAkC,IACxE,IAAI,oBAAoB,GAAG,SAAS,KAAK,sBAAsB;CACrE;CACA,IAAI,SAAS,WAAW,OAAO,CAAC,+BAA+B,KAAK,SAAS,WAAW,GACtF,MAAM,IAAI,oBAAoB,GAAG,SAAS,KAAK,oBAAoB;CACrE,IAAI;CACJ,IAAI;EAAE,SAAS,kBAAkB,SAAS,OAAO,MAAM,IAAI;CAAG,QAAQ;EAAE,MAAM,IAAI,iBAAiB,GAAG,SAAS,KAAK,yBAAyB;CAAG;CAChJ,IAAI,OAAO,UAAU,KAAK,OAAO,UAAU,GAAG,MAAM,IAAI,iBAAiB,GAAG,SAAS,KAAK,qBAAqB,MAAM;CACrH,OAAO;AACT;;;;;;AAOA,eAAsB,SAAS,MAAc,MAAe,SAAkF;CAC5I,MAAM,SAAS,aAAa,QAAQ,QAAQ;CAC5C,IAAI;CACJ,KAAK,MAAM,YAAY,CAAC,QAAQ,GAAG,cAAc,QAAO,MAAK,MAAM,MAAM,CAAC,GACxE,IAAI;EAAE,OAAO;GAAE,GAAG,MAAM,YAAY,UAAU,MAAM,MAAM,OAAO;GAAG,UAAU,SAAS;EAAG;CAAG,SACtF,GAAG;EACR,IAAI,EAAE,aAAa,wBAAwB,QAAQ,QAAQ,SAAS,MAAM;EAC1E,UAAU;CACZ;CAEF,MAAM;AACR;;;;;;;AAQA,eAAsB,iBAAiB,QAAgB,SAA6C;CAClG,MAAM,CAAC,IAAI,MAAM,MAAM,QAAQ,IAAI,CAAC,SAAS,QAAQ,KAAK,OAAO,GAAG,SAAS,QAAQ,QAAQ,OAAO,CAAC,CAAC;CACtG,MAAM,YAAY,CAAC,GAAG,GAAG,SAAS,GAAG,GAAG,OAAO,CAAC,CAAC,KAAI,MAAK,EAAE,IAAI;CAChE,IAAI,CAAC,UAAU,QAAQ,MAAM,IAAI,iBAAiB,GAAG,OAAO,gBAAgB;CAC5E,IAAI,CAAC,UAAU,MAAM,eAAe,GAAG,MAAM,IAAI,iBAAiB,GAAG,OAAO,8DAA8D;AAC5I;;AAGA,eAAsB,eAAe,QAAgB,QAA2B,SAA2D;CACzI,MAAM,iBAAiB,QAAQ,OAAO;CACtC,MAAM,MAAM,aAAa,QAAQ,MAAM;CACvC,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,QAAQ,MAAM,KAAK;GAAE,SAAS,EAAE,QAAQ,mBAAmB;GAAG,UAAU;GAAuB,QAAQ,QAAQ;GAAQ,UAAU;EAAQ,CAAC;CAC7J,SAAS,GAAG;EACV,MAAM,IAAI,iBAAiB,aAAa,KAAK,OAAO,CAAC,CAAC,IAAI,GAAG,IAAI,iBAC7D,GAAG,OAAO,2IAA2I;CAC3J;CACA,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;CACxD,IAAI,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK,MAAM,IAAI,iBAAiB,GAAG,OAAO,gEAAgE,KAAK;CAC/J,IAAI,SAAS,WAAW,KAAK,MAAM,IAAI,iBAAiB,GAAG,OAAO,YAAY,SAAS,QAAQ;CAC/F,IAAI;EAAE,OAAO,IAAI,YAAY,SAAS,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,SAAS,KAAK;CAAG,QAAQ;EAAE,MAAM,IAAI,iBAAiB,GAAG,IAAI,aAAa;CAAG;AAC7I;AAgBA,eAAe,OAAO,QAAgB,QAAsB,SAAyE;CACnI,MAAM,WAAW,aAAa,QAAQ,QAAQ,CAAC,CAAC;CAChD,IAAI,WAAW,OAAO;EACpB,MAAM,SAAS,MAAM,SAAS,aAAa,MAAM,GAAG,OAAO,OAAO;EAClE,MAAM,SAAmB,CAAC;EAC1B,KAAK,MAAM,UAAU,OAAO,QAAQ,MAAM,GAAG,EAAE,GAAK,IAAI;GAAE,OAAO,KAAK,SAAS,OAAO,IAAI,CAAC;EAAG,QAAQ,CAA2B;EACjI,MAAM,QAAQ,OAAO,QAAQ,SAAS,KAAK,IAAI,GAAG,OAAO,QAAQ,KAAI,MAAK,EAAE,GAAG,CAAC,IAAI,MAAO;EAC3F,OAAO;GAAE;GAAQ;GAAQ,UAAU,OAAO;GAAU,SAAS,eAAe,MAAM;GAAG,OAAO,OAAO,QAAQ,SAAS;GAAG,QAAQ,OAAO;GAAe;EAAM;CAC7J;CACA,MAAM,OAAO,MAAM,eAAe,QAAQ,QAAQ,OAAO;CACzD,MAAM,OAAO;EAAE;EAAQ;EAAQ;EAAU,QAAQ;EAAO,SAAS,CAAC;EAAqB,OAAO;CAAc;CAC5G,IAAI,SAAS,KAAA,GAAW,OAAO;EAAE,GAAG;EAAM,OAAO;CAAM;CACvD,IAAI;EACF,OAAO,WAAW,UAAU;GAAE,GAAG;GAAM,OAAO;GAAM,UAAU,aAAa,IAAI;EAAE,IAAI;GAAE,GAAG;GAAM,OAAO;GAAM,SAAS,qBAAqB,IAAI;EAAE;CACnJ,QAAQ;EAAE,MAAM,IAAI,iBAAiB,GAAG,aAAa,QAAQ,MAAM,EAAE,kBAAkB,WAAW,UAAU,WAAW,UAAU,MAAM;CAAG;AAC5I;AAEA,IAAM,wBAAQ,IAAI,IAAkF;;AAKpG,eAAsB,aAAa,aAAqB,QAAsB,SAAqD;CACjI,MAAM,SAAS,gBAAgB,WAAW,GAAG,MAAM,QAAQ,OAAO,KAAK,KAAK,WAAW,aAAa,QAAQ,QAAQ,CAAC,CAAC;CACtH,MAAM,KAAK,GAAG,SAAS,GAAG,OAAO,GAAG;CACpC,MAAM,MAAM,MAAM,IAAI,EAAE;CACxB,IAAI,OAAO,IAAI,QAAQ,IAAI,GAAG;EAAE,MAAM,EAAE,OAAO,MAAM,GAAG,WAAW,MAAM,IAAI;EAAQ,OAAO;CAAQ;CACpG,MAAM,UAAU,IAAI;CACpB,MAAM,QAAQ;EAAE,OAAO,UAAU;EAAc,QAAQ,OAAO,QAAQ,QAAQ;GAAE,GAAG;GAAS;EAAS,CAAC;CAAE;CACxG,MAAM,IAAI,IAAI,KAAK;CACnB,IAAI,MAAM,OAAO,KAAK,MAAM,OAAO,MAAM,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAM;CAC7D,IAAI;EACF,MAAM,EAAE,OAAO,GAAG,WAAW,MAAM,MAAM;EACzC,MAAM,QAAQ,UAAU,KAAK,IAAI,cAAc,KAAK;EACpD,OAAO;CACT,SAAS,GAAG;EACV,IAAI,MAAM,IAAI,EAAE,MAAM,OAAO,MAAM,OAAO,EAAE;EAC5C,MAAM;CACR;AACF;;AAGA,eAAsB,mBAAmB,QAAgB,QAAyB,QAAsB,SAAqD;CAC3J,MAAM,QAAQ,MAAM,aAAa,QAAQ,QAAQ,OAAO;CACxD,IAAI,YAAY,MAAM,SAAS,MAAM,GAAG,OAAO;CAC/C,MAAM,QAAQ,WAAW,QAAQ,qBAAqB,aAAa,MAAM,MAAM,aAAa,MAAM;CAClG,IAAI,MAAM,QAAQ,MAAK,MAAK,EAAE,QAAQ,OAAO,GAAG,GAAG,MAAM,IAAI,iBAAiB,GAAG,MAAM,kCAAkC;CACzH,IAAI,MAAM,QAAQ,QAAQ,MAAM,IAAI,iBAAiB,GAAG,MAAM,+DAA+D;CAC7H,MAAM,IAAI,iBAAiB,WAAW,QAClC,4BAA4B,aAAa,MAAM,IAAI,MAAM,QAAQ,KAAK,4CACtE,MAAM,QAAQ,GAAG,aAAa,MAAM,EAAE,2BAA2B,GAAG,aAAa,MAAM,EAAE,eAAe;AAC9G;;AAGA,eAAsB,YAAY,QAAgB,UAAkB,SAAqD;CACvH,MAAM,QAAQ,MAAM,aAAa,QAAQ,SAAS,OAAO;CACzD,IAAI,MAAM,aAAa,UAAU,OAAO;CACxC,MAAM,MAAM,aAAa,QAAQ,OAAO;CACxC,MAAM,IAAI,iBAAiB,CAAC,MAAM,QAAQ,GAAG,IAAI,kBAAkB,MAAM,WACrE,GAAG,IAAI,+BAA+B,WAAW,GAAG,IAAI,4BAA4B,QAAQ;AAClG;;;;;;;;;;;ACnMA,IAAa,gBAAgB;;AAG7B,IAAa,yBAAyB;AACtC,IAAM,uBAAuB;;;;;AAM7B,SAAgB,eAAuB;CACrC,IAAI;EAEF,OAAgD;CAClD,QAAQ;EAAE,OAAO;CAAe;AAClC;;AAYA,SAAgB,eAAe,KAAa,MAAM,aAAa,GAAW;CACxE,MAAM,SAAS,iBAAiB,GAAG;CACnC,IAAI,WAAW,OAAO,OAAO,GAAG,IAAI,GAAG;CACvC,IAAI,WAAW,OAAO,OAAO,WAAW,IAAI,MAAM,CAAiB,EAAE;CACrE,MAAM,IAAI,MAAM,wBAAwB;AAC1C;;;;;AAMA,eAAsB,mBAAmB,MAAc,SAA+C;CACpG,IAAI;EAAE,MAAM,iBAAiB,MAAM;GAAE,OAAO,QAAQ;GAAO,QAAQ,QAAQ;GAAQ,UAAU,QAAQ;EAAS,CAAC;CAAG,SAC3G,GAAG;EAAE,MAAM,IAAI,MAAM,wBAAwB,KAAK,sBAAsB,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,GAAG;CAAG;AAChI;;AAGA,eAAsB,kBAAkB,KAAa,SAA6D;CAChH,MAAM,MAAM,eAAe,KAAK,QAAQ,GAAG;CAC3C,IAAI,iBAAiB,GAAG,MAAM,OAAO,MAAM,mBAAmB,IAAI,MAAM,CAAiB,GAAG,OAAO;CACnG,IAAI;CACJ,IAAI;EACF,WAAW,MAAM,QAAQ,MAAM,KAAK;GAAE,SAAS,EAAE,QAAQ,4CAA4C;GAAG,UAAU;GAAwB,QAAQ,QAAQ;GAAQ,UAAU;EAAQ,CAAC;CACvL,SAAS,GAAG;EAEV,MAAM,IAAI,MAAM,aAAa,KAAK,OAAO,CAAC,CAAC,IAAI,4CAA4C,yCAAyC;CACtI;CACA,IAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK,MAAM,IAAI,MAAM,yDAAyD;CACjI,IAAI,SAAS,WAAW,KAAK,MAAM,IAAI,MAAM,yCAAyC;CACtF,IAAI;CACJ,IAAI;EAAE,MAAM,KAAK,MAAM,SAAS,IAAI;CAAG,QAAQ;EAAE,MAAM,IAAI,MAAM,yCAAyC;CAAG;CAC7G,OAAO,wBAAwB,KAAK,GAAG;AACzC;;;;;;AAOA,eAAsB,qBAAqB,QAAgB,SAAwD;CACjH,MAAM,SAAS;EAAE,OAAO,QAAQ;EAAO,QAAQ,QAAQ;EAAQ,UAAU,QAAQ;CAAS;CAC1F,IAAI;EACF,MAAM,SAAS,MAAM,SAAS,YAAY,UAAU,OAAO,MAAM;EACjE,MAAM,uBAAO,IAAI,IAAY;EAC7B,KAAK,MAAM,KAAK,OAAO,SAAS;GAC9B,IAAI,EAAE,SAAS,IAAI;GACnB,IAAI;GACJ,IAAI;IAAE,OAAO,SAAS,EAAE,IAAI;GAAG,QAAQ;IAAE;GAAU;GACnD,IAAI,KAAK,WAAW,MAAM,GAAG,KAAK,IAAI,KAAK,MAAM,CAAC,CAAC;EACrD;EACA,IAAI,KAAK,OAAO,GAAG,OAAO;EAC1B,MAAM,CAAC,OAAO;EACd,IAAI,KAAK,OAAO,aAAa,GAAG,IAAI,MAAM;CAC5C,QAAQ,CAAwC;CAChD,IAAI;EACF,MAAM,iBAAiB,QAAQ,MAAM;EACrC,MAAM,WAAW,MAAM,QAAQ,MAAM,WAAW,OAAO,2BAA2B;GAAE,SAAS,EAAE,QAAQ,aAAa;GAAG,UAAU;GAAsB,QAAQ,QAAQ;GAAQ,UAAU;EAAQ,CAAC;EAClM,IAAI,SAAS,WAAW,KAAK,OAAO;EACpC,MAAM,MAAM,SAAS,KAAK,KAAK;EAC/B,OAAO,aAAa,GAAG,IAAI,MAAM;CACnC,QAAQ;EAAE,OAAO;CAAM;AACzB;;;;;AAMA,eAAsB,sBAAsB,KAAyB,SAA6D;CAChI,IAAI,CAAC,IAAI,QAAQ,OAAO,KAAA;CACxB,IAAI;EAAE,OAAQ,MAAM,qBAAqB,IAAI,QAAQ,OAAO,MAAO,IAAI,MAAM,IAAI,SAAS,KAAA;CAAW,QAAQ;EAAE;CAAkB;AACnI"}
|
|
1
|
+
{"version":3,"file":"resolve-DKGaPeMz.js","names":[],"sources":["../../../browser/src/shared/features.ts","../../../browser/src/proofs/verify.ts","../../../browser/src/plugins/bundled.ts","../../../browser/src/plugins/registry.ts","../../../browser/src/proofs/ownDid.ts","../../../browser/src/proofs/domain.ts","../../../browser/src/proofs/atproto/resolve.ts"],"sourcesContent":["/** Release policy: external identity experiments are retained for future work,\n * but must not advertise capabilities, start network lookups, or expose cached\n * external profiles. This does not gate Ghostly participation authentication. */\nexport const EXTERNAL_IDENTITIES_ENABLED: boolean = false;\n\n/** Mini-apps (WISP 1200): `apps/1` on paired sessions and the engine's `app*` calls. On from release 1.2 (a version\n * before 1.2.0 is never cut with it on: `RELEASE_GUARDS` in tools/scripts/changes.mjs). Off, nothing is offered to\n * contacts and every call is refused; a host that runs no apps pins its engine off (`NodeOptions.apps`). */\nexport const APPS_ENABLED: boolean = true;\n\n/**\n * A build that may be put into test mode: a development build (`import.meta.env.DEV`, which vitest also sets) or the\n * e2e suite's build (`VITE_APPS_TEST`, fixed when the build is made, as the mini-app switch is). A release build is\n * neither: Vite folds this to `false` there, so the storage flags the test fakes answer to are ignored. The fakes\n * themselves are still in the bundle (the registries import them); plugins may still pass fakes to the registry.\n */\nexport const testBuild = (): boolean => { try { return !!import.meta.env?.DEV || import.meta.env?.VITE_APPS_TEST === \"1\"; } catch { return false; } };\n","import { boundVerifiedIdentity, IDENTITY_MAX_EVIDENCE, IDENTITY_MAX_VALIDITY, type IdentityStatement, type VerifiedIdentity } from \"@ghostly/core\";\nimport type { IdentityFetch, IdentityProofProvider, IdentitySigner, VerifyContext } from \"./contract\";\n\nconst DAY = 86_400;\n\n/**\n * The checks every proof goes through, whatever its provider: known provider, validity within the\n * provider's limit, bounded evidence, strict parsing, the provider's own check, and the category rule\n * (a self-custodied proof proves exactly the subject it names; an attested one says who attests it).\n * The engine verifies a contact's proof, and the person's own proof before saving it, only through this.\n */\nexport async function verifyIdentity(providers: readonly IdentityProofProvider[], statement: IdentityStatement, evidence: unknown, ctx: VerifyContext): Promise<VerifiedIdentity> {\n const { binding } = statement;\n const provider = providers.find(p => p.id === binding.provider);\n if (!provider) throw new Error(\"This app cannot verify this kind of identity\");\n if (binding.expiresAt - binding.issuedAt > Math.min(provider.validity.maxDays * DAY, IDENTITY_MAX_VALIDITY)) throw new Error(\"The proof lasts longer than this kind of identity allows\");\n if (JSON.stringify(evidence ?? null).length > IDENTITY_MAX_EVIDENCE) throw new Error(\"Evidence too large\");\n const parsed = provider.parseEvidence(evidence);\n const verified = boundVerifiedIdentity(await provider.verify(statement, parsed, ctx));\n if (provider.category === \"self-custodied\" && verified.subject !== binding.subject) throw new Error(\"The evidence is for another identity\");\n if (provider.category === \"provider-attested\" && !verified.attester) throw new Error(\"The evidence does not say who attests it\");\n return verified;\n}\n\n/** Problems with a provider's descriptor, empty when it is well-formed. The registry and the contract suite use it. */\nexport function descriptorProblems(p: IdentityProofProvider): string[] {\n const problems: string[] = [];\n if (!/^[a-z][a-z0-9-]{0,31}$/.test(p.id)) problems.push(\"id must match ^[a-z][a-z0-9-]{0,31}$\");\n if (!p.label?.trim()) problems.push(\"label is empty\");\n if (!p.description?.trim()) problems.push(\"description is empty\");\n if (!p.privacy?.trim()) problems.push(\"privacy is empty: say what verify contacts\");\n if (p.category !== \"self-custodied\" && p.category !== \"provider-attested\") problems.push(\"category is unknown\");\n if (!p.platforms.length) problems.push(\"no platforms\");\n const { defaultDays, maxDays } = p.validity;\n if (!(Number.isInteger(defaultDays) && Number.isInteger(maxDays) && defaultDays >= 1 && defaultDays <= maxDays && maxDays * DAY <= IDENTITY_MAX_VALIDITY)) problems.push(\"validity must be whole days, 1 ≤ default ≤ max ≤ 400\");\n if (p.recheck && !(Number.isInteger(p.recheck.afterSeconds) && p.recheck.afterSeconds >= 60)) problems.push(\"recheck.afterSeconds must be at least 60\");\n if (!p.signers.length) problems.push(\"no signers\");\n const ids = p.signers.map(s => s.id);\n if (new Set(ids).size !== ids.length) problems.push(\"signer ids are not unique\");\n for (const s of p.signers as readonly IdentitySigner<unknown>[]) {\n if (![\"in-app\", \"external-tool\", \"redirect\", \"publish\"].includes(s.kind)) problems.push(`signer ${s.id} has an unknown kind`);\n if (s.kind === \"in-app\" && typeof s.run !== \"function\") problems.push(`signer ${s.id} has no run()`);\n if (s.kind === \"external-tool\" && (typeof s.instructions !== \"function\" || typeof s.parse !== \"function\")) problems.push(`signer ${s.id} needs instructions() and parse()`);\n if (s.kind === \"redirect\" && typeof s.start !== \"function\") problems.push(`signer ${s.id} has no start()`);\n if (s.kind === \"publish\" && (typeof s.instructions !== \"function\" || typeof s.evidence !== \"function\")) problems.push(`signer ${s.id} needs instructions() and evidence()`);\n }\n return problems;\n}\n\n/** Signers of a provider that run on this platform and are available in this window. */\nexport function availableSigners<E>(p: IdentityProofProvider<E>, platform: IdentityProofProvider[\"platforms\"][number]): IdentitySigner<E>[] {\n return p.signers.filter(s => (s.platforms ?? p.platforms).includes(platform) && (s.available?.() ?? true));\n}\n\n/**\n * The engine's `ctx.fetch`: HTTPS GET only, no credentials or referrer, a time-out, a size cap,\n * redirects refused unless asked for.\n * `online` false refuses everything (the person turned the network off).\n */\nexport function boundedIdentityFetch(options: { online: () => boolean; timeoutMs?: number; fetcher?: typeof fetch } = { online: () => true }): IdentityFetch {\n return async (url, { headers, maxBytes = 64 * 1024, signal, redirect = \"error\" } = {}) => {\n if (!options.online()) throw new Error(\"Offline: this identity cannot be checked now\");\n const target = new URL(url);\n if (target.protocol !== \"https:\" || target.username || target.password) throw new Error(\"Identity checks use HTTPS only\");\n const timeout = AbortSignal.timeout(options.timeoutMs ?? 10_000);\n const response = await (options.fetcher ?? fetch)(target.href, {\n headers, signal: signal ? AbortSignal.any([signal, timeout]) : timeout,\n credentials: \"omit\", referrerPolicy: \"no-referrer\", cache: \"no-store\", redirect,\n });\n if (Number(response.headers.get(\"content-length\")) > maxBytes) throw new Error(\"Identity check response too large\");\n const reader = response.body?.getReader();\n const parts: Uint8Array[] = [];\n let length = 0;\n if (reader) {\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n length += value.length;\n if (length > maxBytes) throw new Error(\"Identity check response too large\");\n parts.push(value);\n }\n } finally { await reader.cancel().catch(() => {}); }\n }\n const bytes = new Uint8Array(length);\n let offset = 0;\n for (const part of parts) { bytes.set(part, offset); offset += part.length; }\n return { status: response.status, contentType: response.headers.get(\"content-type\") ?? \"\", text: new TextDecoder().decode(bytes), bytes };\n };\n}\n","import type { GhostlyAdapterPlugin } from \"./registry\";\n\n/**\n * The adapter plugins compiled into this build. Empty unless the build lists some: `GHOSTLY_PLUGINS`\n * names their modules (comma-separated paths from the repository root, each default-exporting a\n * `GhostlyAdapterPlugin`), and the Vite plugin in `packages/browser/vite-plugin.ts` swaps this module\n * for one that imports them. Release builds never set it; the e2e build carries the SDK example.\n */\nexport const BUNDLED_PLUGINS: readonly GhostlyAdapterPlugin[] = [];\n","import type { LightningProviderDescriptor } from \"../engine/paymentAdapters/providers/lightning\";\nimport type { OnchainProviderDescriptor } from \"../engine/paymentAdapters/providers/onchain\";\nimport { providerDescriptorProblems, type ProviderDescriptor, type ProviderKind } from \"../engine/paymentAdapters/providers/types\";\nimport type { IdentityProofProvider } from \"../proofs/contract\";\nimport { descriptorProblems } from \"../proofs/verify\";\nimport { BUNDLED_PLUGINS } from \"./bundled\";\n\n/**\n * Adapters written outside the app: wallet sources (Lightning, on-chain) and identity-proof providers\n * that register here instead of being added to the built-in lists. A plugin is a plain object naming\n * its adapters; the registries (`providers/registry.ts`, `proofs/registry.ts`) list what is registered\n * after the built-ins and before the test fakes, and the same platform and mode rules apply to all.\n *\n * Two ways in:\n * - at build time: `GHOSTLY_PLUGINS` lists the modules and `bundled.ts` is swapped for them;\n * - at run time: code already running in the engine's realm calls `registerAdapters` before the\n * pickers are shown (or after: the engine re-reads the lists when something registers).\n *\n * Trust: a plugin runs with the app's privileges, in the app's own JavaScript realm. There is no\n * sandbox, no permission prompt and no store; whoever builds a plugin in, or loads one, trusts its\n * author with everything the app can do, keys and sats included. A manifest with permissions and an\n * isolated runtime are a later phase (docs/wisps/ADAPTER-ROADMAP.md, \"Plugins, apps, catalogs\").\n *\n * The state lives on `globalThis` under a well-known symbol, so a plugin bundled with its own copy of\n * the SDK (a second copy of this module) still registers into the same lists the app reads.\n */\n\n/** The generation of the adapter contracts. A plugin says which one it was written against. */\nexport const SDK_API = 1;\nexport const PLUGIN_ID = /^[a-z][a-z0-9-]{0,63}$/;\n\nexport interface GhostlyAdapterPlugin {\n /** Stable, unique among plugins: `^[a-z][a-z0-9-]{0,63}$`. */\n id: string;\n /** The plugin's own version, for people. */\n version?: string;\n /** The contract generation it was written against: `SDK_API`. Another one is refused. */\n sdk: number;\n lightning?: readonly LightningProviderDescriptor[];\n onchain?: readonly OnchainProviderDescriptor[];\n identities?: readonly IdentityProofProvider[];\n}\n\nexport type AdapterKind = ProviderKind | \"identity\";\n\ninterface Store {\n plugins: Map<string, GhostlyAdapterPlugin>;\n /** Ids the built-in registries own, per kind: a plugin cannot take one. */\n reserved: Record<AdapterKind, Set<string>>;\n listeners: Set<() => void>;\n seeded: boolean;\n}\n\nconst KEY = Symbol.for(\"ghostly.adapters/1\");\nfunction store(): Store {\n const g = globalThis as unknown as Record<symbol, Store | undefined>;\n return (g[KEY] ??= { plugins: new Map(), reserved: { lightning: new Set(), onchain: new Set(), identity: new Set() }, listeners: new Set(), seeded: false });\n}\n\nconst ids = (kind: AdapterKind, plugin: GhostlyAdapterPlugin): string[] => {\n // Not trusted to be well formed: pluginProblems reads it before saying what is wrong with it.\n const list: unknown = kind === \"identity\" ? plugin.identities : kind === \"lightning\" ? plugin.lightning : plugin.onchain;\n return Array.isArray(list) ? list.map((a: { id?: string } | null) => a?.id as string) : [];\n};\nconst KINDS: readonly AdapterKind[] = [\"lightning\", \"onchain\", \"identity\"];\n\n/** Problems with a plugin, empty when it can be registered. Does not look at what is already registered. */\nexport function pluginProblems(plugin: GhostlyAdapterPlugin): string[] {\n const problems: string[] = [];\n if (!plugin || typeof plugin !== \"object\") return [\"not a plugin object\"];\n if (!PLUGIN_ID.test(plugin.id ?? \"\")) problems.push(\"plugin id must match ^[a-z][a-z0-9-]{0,63}$\");\n if (plugin.sdk !== SDK_API) problems.push(`plugin was written for SDK API ${String(plugin.sdk)}; this app speaks ${SDK_API}`);\n if (plugin.version !== undefined && (typeof plugin.version !== \"string\" || plugin.version.length > 64)) problems.push(\"version must be a short string\");\n for (const kind of [\"lightning\", \"onchain\"] as const) {\n const list = plugin[kind];\n if (list === undefined) continue;\n if (!Array.isArray(list)) { problems.push(`${kind} must be a list of descriptors`); continue; }\n for (const d of list as ProviderDescriptor<unknown>[]) {\n if (!d || typeof d !== \"object\") { problems.push(`${kind} ${String(d)}: not a descriptor`); continue; }\n const own = providerDescriptorProblems(d);\n if (d?.kind && d.kind !== kind) own.push(`is listed under ${kind} but says kind ${String(d.kind)}`);\n problems.push(...own.map((p) => `${kind} ${String(d?.id)}: ${p}`));\n }\n }\n if (plugin.identities !== undefined) {\n if (!Array.isArray(plugin.identities)) problems.push(\"identities must be a list of providers\");\n else for (const p of plugin.identities) {\n if (!p || typeof p !== \"object\") problems.push(`identity ${String(p)}: not a provider`);\n else problems.push(...descriptorProblems(p).map((m) => `identity ${String(p.id)}: ${m}`));\n }\n }\n for (const kind of KINDS) {\n const list = ids(kind, plugin);\n if (new Set(list).size !== list.length) problems.push(`${kind} ids are not unique within the plugin`);\n }\n if (!KINDS.some((kind) => ids(kind, plugin).length)) problems.push(\"the plugin brings no adapter\");\n return problems;\n}\n\n/** The built-in registries say which ids are theirs. A plugin using one is refused. */\nexport function reserveAdapterIds(kind: AdapterKind, list: readonly string[]): void {\n const s = store();\n for (const id of list) s.reserved[kind].add(id);\n}\n\n/**\n * Registers a plugin's adapters. Throws, registering nothing, when the plugin is malformed, its id or\n * one of its adapters' ids is taken (by a built-in or by another plugin), or its contract generation\n * is another one. Returns the function that unregisters it.\n */\nexport function registerAdapters(plugin: GhostlyAdapterPlugin): () => void {\n const problems = pluginProblems(plugin);\n const s = store();\n if (!problems.length) {\n if (s.plugins.has(plugin.id)) problems.push(`a plugin with id ${plugin.id} is already registered`);\n for (const kind of KINDS) for (const id of ids(kind, plugin)) {\n if (s.reserved[kind].has(id)) problems.push(`${kind} ${id} is a built-in of this app`);\n for (const other of s.plugins.values()) if (ids(kind, other).includes(id)) problems.push(`${kind} ${id} is already registered by plugin ${other.id}`);\n }\n }\n if (problems.length) throw new Error(`Cannot register plugin ${String(plugin?.id)}: ${problems.join(\"; \")}`);\n s.plugins.set(plugin.id, plugin);\n notify(s);\n return () => { if (s.plugins.get(plugin.id) === plugin) { s.plugins.delete(plugin.id); notify(s); } };\n}\n\nfunction notify(s: Store) { for (const listener of s.listeners) { try { listener(); } catch { /* a listener's problem */ } } }\n\n/** Called when a plugin registers or unregisters: the engine re-reads the lists. */\nexport function onAdaptersChanged(listener: () => void): () => void {\n const s = store();\n s.listeners.add(listener);\n return () => { s.listeners.delete(listener); };\n}\n\n/** Every registered plugin, in registration order (bundled ones first). */\nexport function registeredPlugins(): readonly GhostlyAdapterPlugin[] { seed(); return [...store().plugins.values()]; }\nexport function registeredLightningProviders(): readonly LightningProviderDescriptor[] { return registeredPlugins().flatMap((p) => p.lightning ?? []); }\nexport function registeredOnchainProviders(): readonly OnchainProviderDescriptor[] { return registeredPlugins().flatMap((p) => p.onchain ?? []); }\nexport function registeredIdentityProviders(): readonly IdentityProofProvider[] { return registeredPlugins().flatMap((p) => p.identities ?? []); }\n\n/**\n * The plugins compiled into this build register once, when they are first asked for. A broken one is\n * reported and skipped rather than taking the app down with it; the e2e that expects it fails instead.\n */\nfunction seed() {\n const s = store();\n if (s.seeded) return;\n s.seeded = true;\n for (const plugin of BUNDLED_PLUGINS) {\n try { registerAdapters(plugin); }\n catch (error) { console.error(`[ghostly] a bundled adapter plugin was not loaded: ${error instanceof Error ? error.message : String(error)}`); }\n }\n}\n\n/** Tests only: forget every registration, including the bundled ones. */\nexport function resetAdapterRegistry(): void {\n const s = store();\n s.plugins.clear(); s.seeded = false;\n for (const kind of KINDS) s.reserved[kind].clear();\n notify(s);\n}\n","/**\n * The profile's own Ghostly did:dht, which the DID provider refuses as an external identity. The UI and the engine each\n * set where to read it. Here, not in the provider, so setting it does not load the providers.\n */\nlet source: () => string | undefined = () => undefined;\nexport function setOwnDidSource(read: () => string | undefined): void { source = read; }\nexport const ownDid = (): string | undefined => source();\n","import {\n DOMAIN_FILE_MAX_BYTES, decodeDnsResponse, dnsProofName, encodeDnsQuery, isPublicAddress, nip05RootKey, normalizeDomain,\n recordsFromTxt, recordsFromWellKnown, recordsName, toBase64Url, txtValue, wellKnownUrl,\n type DnsResponse, type DnsType, type DomainMethod, type DomainRecord,\n} from '@ghostly/core';\nimport type { IdentityFetch } from './contract';\n\n/**\n * Network side of domain proofs: DNS TXT through DNS over HTTPS and the\n * `/.well-known/` files, under strict limits. Nothing here trusts the prover:\n * the domain comes from the signed binding, the URLs are built here, every\n * answer is bounded and parsed strictly, and lookups are cached only briefly.\n *\n * What a check reveals, and to whom:\n * - DNS: the chosen resolver learns that this device looked up `_ghostly.<domain>`\n * (the next one in DOH_RESOLVERS too, when the chosen one gives no answer).\n * The domain's own servers see only the resolver.\n * - HTTPS / NIP-05: the resolver learns the domain (its addresses are looked up\n * first, to refuse private networks), and the domain's web server — run by\n * the person being checked — sees this device's IP address and when.\n */\n\nexport type DohResolverId = 'quad9' | 'cloudflare' | 'google';\nexport interface DohResolver { id: DohResolverId; name: string; url: string }\n/** Public resolvers that answer RFC 8484 wire-format GETs with CORS (checked 2026-09-23). */\nexport const DOH_RESOLVERS: readonly DohResolver[] = [\n { id: 'quad9', name: 'Quad9', url: 'https://dns.quad9.net/dns-query' },\n { id: 'cloudflare', name: 'Cloudflare', url: 'https://cloudflare-dns.com/dns-query' },\n { id: 'google', name: 'Google', url: 'https://dns.google/dns-query' },\n];\nexport const DEFAULT_RESOLVER: DohResolverId = 'quad9';\nexport const resolverById = (id: string | null | undefined): DohResolver =>\n DOH_RESOLVERS.find(r => r.id === id) ?? DOH_RESOLVERS.find(r => r.id === DEFAULT_RESOLVER)!;\n\n/** The person's resolver choice, per browser profile (UI and engine share the origin). */\nexport const RESOLVER_SETTING = 'ghostly-doh-resolver';\nexport function chosenResolver(): DohResolver {\n try { return resolverById(globalThis.localStorage?.getItem(RESOLVER_SETTING)); } catch { return resolverById(undefined); }\n}\nexport function chooseResolver(id: DohResolverId): void {\n try { globalThis.localStorage?.setItem(RESOLVER_SETTING, resolverById(id).id); } catch { /* not persisted: the default stays */ }\n}\n\nexport const DNS_MAX_BYTES = 16 * 1024;\n/**\n * Lookups are shared between checks for the DNS TTL, capped: never staler than the resolver itself would\n * be, so a re-check sees a removal as soon as DNS does. Files have no TTL and are only shared in flight.\n */\nconst CACHE_MAX_MS = 30_000, CACHE_FILE_MS = 0;\n\n/** The contract's `ctx.fetch`: HTTPS GET, no credentials, bounded, redirects refused unless asked, with raw bytes. */\nexport type DomainFetch = IdentityFetch;\n\nexport interface DomainLookupOptions {\n fetch: DomainFetch;\n resolver?: DohResolverId;\n signal?: AbortSignal;\n /** Milliseconds. */\n now?: () => number;\n}\n\n/** A check that did not confirm the record, with a message for people. */\nexport class DomainCheckError extends Error {}\n\n/** A resolver that gave no DNS answer at all: not reached, or it refused the request. The next one may answer. */\nclass ResolverUnavailable extends DomainCheckError {}\n\n/** One RFC 8484 GET to one resolver. The query has ID 0 and no client subnet, so it carries only the name. */\nasync function askResolver(resolver: DohResolver, name: string, type: DnsType, options: DomainLookupOptions): Promise<DnsResponse> {\n let response: Awaited<ReturnType<DomainFetch>>;\n try {\n response = await options.fetch(`${resolver.url}?dns=${toBase64Url(encodeDnsQuery(name, type))}`, {\n headers: { accept: 'application/dns-message' }, maxBytes: DNS_MAX_BYTES, signal: options.signal, redirect: 'error' });\n } catch (e) {\n throw /too large/i.test(String(e))\n ? new DomainCheckError(`${resolver.name} sent an answer that is too large`)\n : new ResolverUnavailable(`${resolver.name} could not be reached`);\n }\n if (response.status !== 200 || !/^application\\/dns-message\\b/i.test(response.contentType))\n throw new ResolverUnavailable(`${resolver.name} refused the lookup`);\n let answer: DnsResponse;\n try { answer = decodeDnsResponse(response.bytes, name, type); } catch { throw new DomainCheckError(`${resolver.name} sent an unusable answer`); }\n if (answer.rcode !== 0 && answer.rcode !== 3) throw new DomainCheckError(`${resolver.name} could not resolve ${name}`);\n return answer;\n}\n\n/**\n * A lookup through the chosen resolver, and through the others in turn (in list order) only when it gives no DNS\n * answer at all. Quad9, for one, cannot be read from WebKit (the Mac desktop app, Safari): its HTTP/3 answers carry\n * no CORS header. An answer, even \"no such name\" or a failure, is never asked again elsewhere. `resolver`: who answered.\n */\nexport async function dohQuery(name: string, type: DnsType, options: DomainLookupOptions): Promise<DnsResponse & { resolver: DohResolverId }> {\n const chosen = resolverById(options.resolver);\n let first: DomainCheckError | undefined;\n for (const resolver of [chosen, ...DOH_RESOLVERS.filter(r => r !== chosen)]) {\n try { return { ...await askResolver(resolver, name, type, options), resolver: resolver.id }; }\n catch (e) {\n if (!(e instanceof ResolverUnavailable) || options.signal?.aborted) throw e;\n first ??= e;\n }\n }\n throw first!;\n}\n\n/**\n * Refuses a domain whose addresses are not all public before its web server is\n * contacted, so a proof cannot make a contact's app probe their own network.\n * The browser resolves again when it fetches; a name that changes its answer in\n * between (rebinding) is not fully excluded by this check — see the draft.\n */\nexport async function assertPublicHost(domain: string, options: DomainLookupOptions): Promise<void> {\n const [v4, v6] = await Promise.all([dohQuery(domain, 'A', options), dohQuery(domain, 'AAAA', options)]);\n const addresses = [...v4.answers, ...v6.answers].map(a => a.data);\n if (!addresses.length) throw new DomainCheckError(`${domain} has no address`);\n if (!addresses.every(isPublicAddress)) throw new DomainCheckError(`${domain} points to a private network address, so it was not contacted`);\n}\n\n/** A well-known file: https only, no redirects, bounded. `undefined` when the server says it is not there. */\nexport async function fetchWellKnown(domain: string, method: 'https' | 'nip05', options: DomainLookupOptions): Promise<string | undefined> {\n await assertPublicHost(domain, options);\n const url = wellKnownUrl(domain, method);\n let response: Awaited<ReturnType<DomainFetch>>;\n try {\n response = await options.fetch(url, { headers: { accept: 'application/json' }, maxBytes: DOMAIN_FILE_MAX_BYTES, signal: options.signal, redirect: 'error' });\n } catch (e) {\n throw new DomainCheckError(/too large/i.test(String(e)) ? `${url} is too large`\n : `${domain} could not be reached. The file must be served at exactly this address, without a redirect, with the header Access-Control-Allow-Origin: *`);\n }\n if (response.status === 404 || response.status === 410) return;\n if (response.status >= 300 && response.status < 400) throw new DomainCheckError(`${domain} answered with a redirect; the file must be served at exactly ${url}`);\n if (response.status !== 200) throw new DomainCheckError(`${domain} answered ${response.status}`);\n try { return new TextDecoder('utf-8', { fatal: true }).decode(response.bytes); } catch { throw new DomainCheckError(`${url} is not text`); }\n}\n\nexport interface DomainLookup {\n domain: string;\n method: DomainMethod;\n /** DNS / HTTPS: the Ghostly records found. */\n records: DomainRecord[];\n /** NIP-05: the Nostr key named for the domain itself. */\n nostrKey?: string;\n /** A record or file exists at all (as opposed to nothing there). */\n found: boolean;\n /** The resolver reported DNSSEC validation of the TXT answer. */\n dnssec: boolean;\n resolver: DohResolverId;\n}\n\nasync function lookup(domain: string, method: DomainMethod, options: DomainLookupOptions): Promise<DomainLookup & { ttlMs: number }> {\n const resolver = resolverById(options.resolver).id;\n if (method === 'dns') {\n const answer = await dohQuery(dnsProofName(domain), 'TXT', options);\n const values: string[] = [];\n for (const record of answer.answers.slice(0, 32)) { try { values.push(txtValue(record.data)); } catch { /* not text: not ours */ } }\n const ttlMs = answer.answers.length ? Math.min(...answer.answers.map(a => a.ttl)) * 1000 : 0;\n return { domain, method, resolver: answer.resolver, records: recordsFromTxt(values), found: answer.answers.length > 0, dnssec: answer.authenticated, ttlMs };\n }\n const text = await fetchWellKnown(domain, method, options);\n const base = { domain, method, resolver, dnssec: false, records: [] as DomainRecord[], ttlMs: CACHE_FILE_MS };\n if (text === undefined) return { ...base, found: false };\n try {\n return method === 'nip05' ? { ...base, found: true, nostrKey: nip05RootKey(text) } : { ...base, found: true, records: recordsFromWellKnown(text) };\n } catch { throw new DomainCheckError(`${wellKnownUrl(domain, method)} is not a valid ${method === 'nip05' ? 'NIP-05' : 'Ghostly'} file`); }\n}\n\nconst cache = new Map<string, { until: number; result: Promise<DomainLookup & { ttlMs: number }> }>();\n/** Tests only. */\nexport function clearDomainCache(): void { cache.clear(); }\n\n/** What a domain publishes by one method. Concurrent and back-to-back checks share one lookup. */\nexport async function lookupDomain(domainInput: string, method: DomainMethod, options: DomainLookupOptions): Promise<DomainLookup> {\n const domain = normalizeDomain(domainInput), now = options.now ?? Date.now, resolver = resolverById(options.resolver).id;\n const id = `${resolver}|${method}|${domain}`;\n const hit = cache.get(id);\n if (hit && hit.until > now()) { const { ttlMs: _ttl, ...result } = await hit.result; return result; }\n const started = now();\n const entry = { until: started + CACHE_MAX_MS, result: lookup(domain, method, { ...options, resolver }) };\n cache.set(id, entry);\n if (cache.size > 128) cache.delete(cache.keys().next().value!);\n try {\n const { ttlMs, ...result } = await entry.result;\n entry.until = started + Math.min(CACHE_MAX_MS, ttlMs);\n return result;\n } catch (e) {\n if (cache.get(id) === entry) cache.delete(id);\n throw e;\n }\n}\n\n/** Throws unless `domain` publishes `record` by `method` (DNS or HTTPS). Returns what was found. */\nexport async function assertDomainRecord(domain: string, method: 'dns' | 'https', record: DomainRecord, options: DomainLookupOptions): Promise<DomainLookup> {\n const found = await lookupDomain(domain, method, options);\n if (recordsName(found.records, record)) return found;\n const where = method === 'dns' ? `The TXT record at ${dnsProofName(domain)}` : wellKnownUrl(domain);\n if (found.records.some(r => r.key === record.key)) throw new DomainCheckError(`${where} is for another proof of this key`);\n if (found.records.length) throw new DomainCheckError(`${where} names another Ghostly key: this proof was replaced or removed`);\n throw new DomainCheckError(method === 'dns'\n ? `No Ghostly TXT record at ${dnsProofName(domain)}${found.found ? '' : ' (DNS changes can take a few minutes)'}`\n : found.found ? `${wellKnownUrl(domain)} names no Ghostly proof` : `${wellKnownUrl(domain)} was not found`);\n}\n\n/** Throws unless the domain's NIP-05 root name is `nostrKey`. */\nexport async function assertNip05(domain: string, nostrKey: string, options: DomainLookupOptions): Promise<DomainLookup> {\n const found = await lookupDomain(domain, 'nip05', options);\n if (found.nostrKey === nostrKey) return found;\n const url = wellKnownUrl(domain, 'nip05');\n throw new DomainCheckError(!found.found ? `${url} was not found` : found.nostrKey\n ? `${url} names another Nostr key for ${domain}` : `${url} has no root name \"_\" for ${domain}`);\n}\n","import { atprotoDidMethod, isAtprotoDid, parseAtprotoDidDocument, txtValue, type AtprotoDidDocument } from \"@ghostly/core\";\nimport type { IdentityFetch } from \"../contract\";\nimport { assertPublicHost, dohQuery, type DohResolverId } from \"../domain\";\n\n/**\n * AT Protocol identity resolution, the network half: a DID to its document (the PLC directory for\n * did:plc, the host's `/.well-known/did.json` for did:web), and a handle to a DID (DNS TXT\n * `_atproto.<handle>` through the person's DNS-over-HTTPS resolver, then\n * `https://<handle>/.well-known/atproto-did`). Every request goes through the contract's bounded\n * fetch: HTTPS only, no redirects, a size cap, a time-out. URLs are built here from the DID or the\n * handle, never taken from a proof.\n */\n\nexport const PLC_DIRECTORY = \"https://plc.directory\";\nconst TEST_HOST = /^https:\\/\\/[a-z0-9-]+(\\.[a-z0-9-]+)*\\.test$/;\n/** DID documents are small; a large answer is not one. */\nexport const DID_DOCUMENT_MAX_BYTES = 32 * 1024;\nconst HANDLE_DID_MAX_BYTES = 2048;\n\n/**\n * The PLC directory. A build made for the e2e suite with VITE_ATPROTO_TEST_PLC may point it at a\n * `.test` host (a name reserved for testing); a release build always uses plc.directory.\n */\nexport function plcDirectory(): string {\n try {\n const value = import.meta.env?.VITE_ATPROTO_TEST_PLC as string | undefined;\n return value && TEST_HOST.test(value) ? value : PLC_DIRECTORY;\n } catch { return PLC_DIRECTORY; }\n}\n\nexport interface AtprotoResolveOptions {\n fetch: IdentityFetch;\n signal?: AbortSignal;\n /** The DoH resolver for handles (the person's choice, as for domains). */\n resolver?: DohResolverId;\n /** The PLC directory; plcDirectory() by default. */\n plc?: string;\n}\n\n/** Where a DID's document lives. */\nexport function didDocumentUrl(did: string, plc = plcDirectory()): string {\n const method = atprotoDidMethod(did);\n if (method === \"plc\") return `${plc}/${did}`;\n if (method === \"web\") return `https://${did.slice(\"did:web:\".length)}/.well-known/did.json`;\n throw new Error(\"Not an AT Protocol DID\");\n}\n\n/**\n * Refuses a host the account chose (a did:web host, the PDS its document names) that points to a private\n * network address: a contact's app never knocks on its own local network for someone else's proof.\n */\nexport async function assertPublicServer(host: string, options: AtprotoResolveOptions): Promise<void> {\n try { await assertPublicHost(host, { fetch: options.fetch, signal: options.signal, resolver: options.resolver }); }\n catch (e) { throw new Error(`The account's server ${host} was not contacted: ${e instanceof Error ? e.message : String(e)}`); } // eslint-disable-line preserve-caught-error -- The domain check's message says why; ES2020 has no Error.cause.\n}\n\n/** A DID's document, checked (parseAtprotoDidDocument). Throws a message people can read. */\nexport async function resolveAtprotoDid(did: string, options: AtprotoResolveOptions): Promise<AtprotoDidDocument> {\n const url = didDocumentUrl(did, options.plc);\n if (atprotoDidMethod(did) === \"web\") await assertPublicServer(did.slice(\"did:web:\".length), options);\n let response: Awaited<ReturnType<IdentityFetch>>;\n try {\n response = await options.fetch(url, { headers: { accept: \"application/did+ld+json, application/json\" }, maxBytes: DID_DOCUMENT_MAX_BYTES, signal: options.signal, redirect: \"error\" });\n } catch (e) {\n // eslint-disable-next-line preserve-caught-error -- A message people can act on; the library's error stays out of the UI (ES2020 has no Error.cause).\n throw new Error(/too large/i.test(String(e)) ? \"The account's DID document is too large\" : \"The account's DID could not be resolved\");\n }\n if (response.status === 404 || response.status === 410) throw new Error(\"The account's DID is not registered, or was deactivated\");\n if (response.status !== 200) throw new Error(\"The account's DID could not be resolved\");\n let doc: unknown;\n try { doc = JSON.parse(response.text); } catch { throw new Error(\"The account's DID document is malformed\"); }\n return parseAtprotoDidDocument(doc, did);\n}\n\n/**\n * The DID a handle points to, or null when it points nowhere (or to two different DIDs). DNS first,\n * then HTTPS, as the handle spec says. The HTTPS lookup first checks the handle's addresses are public,\n * so a handle cannot make a contact's app knock on its local network.\n */\nexport async function resolveAtprotoHandle(handle: string, options: AtprotoResolveOptions): Promise<string | null> {\n const lookup = { fetch: options.fetch, signal: options.signal, resolver: options.resolver };\n try {\n const answer = await dohQuery(`_atproto.${handle}`, \"TXT\", lookup);\n const dids = new Set<string>();\n for (const a of answer.answers) {\n if (a.type !== 16) continue;\n let text: string;\n try { text = txtValue(a.data); } catch { continue; }\n if (text.startsWith(\"did=\")) dids.add(text.slice(4));\n }\n if (dids.size > 1) return null;\n const [did] = dids;\n if (did) return isAtprotoDid(did) ? did : null;\n } catch { /* The resolver failed: try HTTPS. */ }\n try {\n await assertPublicHost(handle, lookup);\n const response = await options.fetch(`https://${handle}/.well-known/atproto-did`, { headers: { accept: \"text/plain\" }, maxBytes: HANDLE_DID_MAX_BYTES, signal: options.signal, redirect: \"error\" });\n if (response.status !== 200) return null;\n const did = response.text.trim();\n return isAtprotoDid(did) ? did : null;\n } catch { return null; }\n}\n\n/**\n * The handle to show for a DID: the one its document claims, and only if that handle resolves back to\n * the same DID. Otherwise nothing: the card shows the DID. Never throws.\n */\nexport async function verifiedAtprotoHandle(doc: AtprotoDidDocument, options: AtprotoResolveOptions): Promise<string | undefined> {\n if (!doc.handle) return undefined;\n try { return (await resolveAtprotoHandle(doc.handle, options)) === doc.did ? doc.handle : undefined; } catch { return undefined; }\n}\n"],"mappings":"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"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { n as traceJoin } from "./joinTrace-CjRDFy85.js";
|
|
2
|
-
import { $c as currentRelays, $i as revokesIdentity, $n as GROUP_FILE_LIMITS, $r as WAKE_CALL_INTERVAL_MS, $t as didDhtFromPublicKey, A as CommunitySession, Aa as forwardedAgain, Ac as devicePingFrame, Ao as rosterAdmin, Ar as newerHead, As as handoffOfferFrame, B as knockRecords, Ba as readReaction, Bc as TURN_MAX, Bi as capsDescriptors, Bn as findEndpoint, Bo as GhostlyHttpError, Br as transferStalled, Bs as readHandoffHave, C as sha256Paced, Ca as parseImageMeta, Cc as DEVICES_CAPABILITY, Ci as readManifest, Cl as randomBytes, Cn as isBitcoinAddress, Cr as beaconRecords, Cs as handoffContext, D as openGroupTyping, Da as RateWindow, Dc as deviceEchoNonce, Dl as utf8Encode, Do as MEMBER_KEY, Dr as lobbyRecords, Ds as handoffEphemeral, E as groupTypingEpoch, Ea as EDIT_RATE_WINDOW_MS, Ec as deviceEchoFrame, El as utf8Decode, Er as lobbyKeys, Es as handoffDigest, Et as normalizeAtprotoHandle, Fa as ReactionWindow, Fc as TURN_RAISE_READ_TIMEOUT_MS, Fr as readLobby, Fs as handoffVersions, G as groupWakeFrame, Ga as replySnippet, Gc as signTurnRelease, Gn as INVITE_TAKEN, Go as decodeControl, Gr as typingActivity, Gs as sealHandoffPiece, H as readKnocks, Ha as wireReaction, Hc as nextTurnPosition, Hn as parseCashuRequestPayload, Ho as parseLocalTarget, Hs as readHandoffPake, I as decodeGroupEntryLink, Ia as nextReactionNumber, Ic as TURN_SETTLE_MS, In as decodeBolt11, Io as DHT_POLL_INTERVALS, Ir as shouldBeHub, Is as newHandoffId, J as GROUP_LIMITS, Jc as turnName, Ji as emptyIdentityLedger, Jn as pairedMessageFits, Jo as RTC_CONFIG, Jr as mayPin, Js as readSetUpdate, K as groupWakes, Ka as BUTTON_ID, Kc as turnInstance, Ki as IdentityExchange, Kn as LIVENESS_PING_MS, Ko as encodeControl, L as encodeGroupEntryLink, La as queueReaction, Lc as classifyTurnRead, Ln as ENDPOINT, Lr as ChatFiles, Ls as readHandoffAck, M as communityHasFrame, Ma as COMMUNITY_REACTION_FRAME, Mc as seedSigner, Mo as verifyCommitSignature, Mr as rankHubs, Ms as handoffReleaseFrame, N as decodeCommunityLink, Na as GROUP_REACTION_FRAME, Nc as webCryptoSigner, No as edgeParams, Nr as readBeacon, Ns as handoffRetryAfter, O as sealGroupTyping, Oa as dhtEditId, Oc as deviceKeyZ32, Oo as commitHash, Or as mergeBeacon, Os as handoffHelloFrame, P as encodeCommunityLink, Pa as REACTION_LIMITS, Po as DirectPathWatch, Pr as readBeaconHead, Ps as handoffStreamKey, Q as frameBytes, Qc as RelayTransport, Qi as receivedIdentityStatus, Qn as parseEngineError, Qr as readPin, Qs as verifySetUpdate, Qt as didDhtDocument, R as entryParams, Ra as reactionEmoji, Rc as turnPutSummary, Ri as CapsExchange, Rn as cashuRequestPayload, Ro as RELAY_POLL_INTERVALS, Rr as FILE_LIMITS, Rs as readHandoffCancel, S as readAppBundleAsync, Sa as parseVideoMeta, Si as newMailbox, Sn as sparkInvoiceDetails, So as canonicalJson, Sr as beaconKeys, Ss as handoffCancelFrame, T as GroupTypingBoard, Ta as EDIT_BUFFER_MS, Tc as HANDOFF_CAPABILITY, Tl as toZ32, Tn as isPubkyKey, To as GROUP_MEMBER_CAP, Tr as freshHubs, Ts as handoffDataFrame, Tt as isAtprotoDid, Ua as pairedReplyAuthor, Uc as readTurnPacket, Un as parseFedimintRequestPayload, Uo as webLocalFetch, Ur as TypingSender, Us as readHandoffTurnFrame, V as mergeKnocks, Va as validReactionNumber, Vc as firstDeviceSetSecret, Vi as dialDescriptors, Vn as isFederationId, Vo as formatLocalTarget, Vs as readHandoffHello, W as GroupWakeLimiter, Wa as readReply, Wc as signTurnPacket, Wi as IDENTITY_REVOCATION_LABEL, Wn as GhostLink, Wo as LIMITS, Ws as readHandoffVerified, X as GROUP_READ_NOTE, Xc as turnVerifierMark, Xi as identityStatement, Xn as engineError, Xr as pinIsNewer, Xs as setUpdateFrame, Yc as turnStatedVerifier, Yi as identityRevocationValue, Yn as pairedMessageFrame, Yr as nextPinNumber, Ys as setAckFrame, Z as GroupSession, Za as STATUS_CARD_LIMITS, Zc as DEFAULT_RELAYS, Zi as newIdentityBinding, Zn as engineText, Zr as pinNumberHolds, Zs as signTombstone, _c as createChatInvite, _i as HOLD_DATED_BACK_MS, _n as validatePaymentTarget, _o as isAppRef, _r as MESH_HUBS, _s as filePartName, a as planAppUpdate, aa as automaticTransport, ac as enrollDigits, ai as wakeRequest, al as withRequestOptions, an as EVM_TEST_CHAINS, ao as arrivalKey, as as serviceIdFromName, at as groupName, b as pacer, ba as parseVoiceMeta, bi as HoldRefusedError, bl as bytesEqual, bn as SPARK_PROVIDER, br as pickMeshHubs, bs as handoffAttemptSucceeded, cc as enrollHelloFrame, cl as createRelayPayload, cn as SEPOLIA_TEST_USDT, co as receivedTimestamp, cs as HANDOFF_DONE, d as APP_BUNDLE_LIMITS, da as DHT_FILE_CAPABILITY, dc as readEnrollHello, di as APPS_CAPABILITY, dn as USDT_PUBLIC_RPC, do as APP_STATEMENT_LIMITS, ds as HANDOFF_OFFER, ea as lastSharedWithMe, ei as WakeLimiter, el as normalizeRelayUrl, en as encodeDidDhtDeactivated, es as parseCallSignal, f as APP_BUNDLE_MAGIC, fa as dhtFileId, fc as verifyEnrollProof, fi as BUTTONS_CAPABILITY, fl as createIdentity, fn as WALLET_NETWORKS, fo as appFingerprint, fs as HANDOFF_PAKE, g as appViewOf, gc as OwnInviteError, gi as HOLD_CAPABILITY, gl as verify, gn as formatPaymentAmount, go as isAppKey, gr as readGroupSignal, gs as HANDOFF_VERIFIED, h as appDigest, ha as sanitizeMime, hc as readDeviceInvite, hi as UPGRADE_CAPABILITY, hl as publicKeyFromZ32, hn as assertWholeSats, ho as isAppHash, hr as groupSignalFrame, hs as HANDOFF_TIMINGS, i as checkAppBeforeRun, ia as TRANSPORTS, ic as enrollCancelReason, ii as relayRequest, il as isDiscoveryBudgetError, in as ETHEREUM_USDT, io as statusCardText, ir as groupFileFallback, is as LEGACY_SERVICES, it as mentionsMember, j as GROUP_READ_NOTE_COMMUNITY, ja as readForwarded, jc as newDeviceSetSecret, jo as rosterHas, jr as pickHubs, js as handoffPakeFrame, k as COMMUNITY_LIMITS, ka as parseLinkPreview, kc as deviceLinkPairing, ko as parseGroupCommit, kr as mergeLobby, ks as handoffManifestFrames, l as readAppStoreSteps, la as DHT_MESSAGE_TTL, lc as enrollProofFrame, li as chatAppId, lo as shownTime, ls as HANDOFF_HAVE, ma as sanitizeFileName, mc as deviceInviteJoinerParams, mi as STATUS_CARD_CAPABILITY, ml as identityFromSeedB64, mn as assertTokenUnits, ms as HANDOFF_REQUEST, n as appStoreDecision, na as emptyProofLedger, ni as newWakeToken, nl as traceLink, no as checkStatusCard, ns as emptyLinkRecords, nt as carryMentions, o as APP_STORE_LIMITS, oc as enrollDoneFrame, oi as checkPushEndpoint, ol as PacketTooLargeError, on as ONCHAIN_PROVIDER, oo as claimedTime, or as readGroupFileMeta, os as HANDOFF_ACK, p as APP_ICON_PATH, pa as formatFileSize, pc as createDeviceInvite, pi as EDIT_CAPABILITY, pl as identityFromSeed, pn as arkAddressPrefix, po as appRef, ps as HANDOFF_PIECE_BYTES, q as parseGroupWakeFrame, qc as turnKeys, qn as PAIRED_FRAME_TOO_LARGE, qr as PIN_LIMITS, r as appUpdateDecision, ra as validExternalKey, rc as enrollCancelFrame, ri as parseWakeFrame, rl as budgetRetryMs, rn as signDidDhtPacket, ro as sameButtonText, rs as HTTP_SERVICE_PROTO, rt as parseCommunityEdit, sc as enrollGrantFrame, si as vapidKeysMatch, sn as PaymentPreflightError, so as heardTime, ss as HANDOFF_CANCEL, t as appRevocationFor, ta as PeerProofs, ti as deviceWakeRequest, tn as encodeDidDhtPacket, tt as GROUP_EDIT_TEXT_BYTES, ua as peekDhtMailbox, uc as readEnrollGrant, ui as isAppVersion, un as TEST_USDT_FAUCET_AMOUNT, ur as CarriedTransport, us as HANDOFF_HELLO, vc as decodeInviteCode, vi as HOLD_LIMITS, vl as sanitizeAvatar, vn as walletNetworkOf, vo as readAppRevocation, vr as mayBeHub, vs as handoffAttemptAllowed, wc as ENROLL_CAPABILITY, wl as toBase64Url, wo as readCanonicalJson, wr as doorHubs, ws as handoffContextProof, xc as inviteOwnership, xi as isHoldUrl, xl as fromBase64Url, xn as sparkAddressKind, xr as COMMUNITY_TOPOLOGY, xs as handoffBusyFrame, y as isAppUrl, ya as fileMessageText, yc as encodeInviteCode, yi as HoldKeys, yl as sanitizeDisplayText, yn as SPARK_NETWORKS, yr as meshHubs, ys as handoffAttemptFailed, z as knockIdentity, za as reactionIsNewer, zc as TURN_LAST_SEQUENCE, zi as DHT_TEXT_CAPABILITY, zn as fedimintRequestPayload, zo as presenceSeenAt, zr as transferEnded, zs as readHandoffDone } from "./src-
|
|
2
|
+
import { $c as currentRelays, $i as revokesIdentity, $n as GROUP_FILE_LIMITS, $r as WAKE_CALL_INTERVAL_MS, $t as didDhtFromPublicKey, A as CommunitySession, Aa as forwardedAgain, Ac as devicePingFrame, Ao as rosterAdmin, Ar as newerHead, As as handoffOfferFrame, B as knockRecords, Ba as readReaction, Bc as TURN_MAX, Bi as capsDescriptors, Bn as findEndpoint, Bo as GhostlyHttpError, Br as transferStalled, Bs as readHandoffHave, C as sha256Paced, Ca as parseImageMeta, Cc as DEVICES_CAPABILITY, Ci as readManifest, Cl as randomBytes, Cn as isBitcoinAddress, Cr as beaconRecords, Cs as handoffContext, D as openGroupTyping, Da as RateWindow, Dc as deviceEchoNonce, Dl as utf8Encode, Do as MEMBER_KEY, Dr as lobbyRecords, Ds as handoffEphemeral, E as groupTypingEpoch, Ea as EDIT_RATE_WINDOW_MS, Ec as deviceEchoFrame, El as utf8Decode, Er as lobbyKeys, Es as handoffDigest, Et as normalizeAtprotoHandle, Fa as ReactionWindow, Fc as TURN_RAISE_READ_TIMEOUT_MS, Fr as readLobby, Fs as handoffVersions, G as groupWakeFrame, Ga as replySnippet, Gc as signTurnRelease, Gn as INVITE_TAKEN, Go as decodeControl, Gr as typingActivity, Gs as sealHandoffPiece, H as readKnocks, Ha as wireReaction, Hc as nextTurnPosition, Hn as parseCashuRequestPayload, Ho as parseLocalTarget, Hs as readHandoffPake, I as decodeGroupEntryLink, Ia as nextReactionNumber, Ic as TURN_SETTLE_MS, In as decodeBolt11, Io as DHT_POLL_INTERVALS, Ir as shouldBeHub, Is as newHandoffId, J as GROUP_LIMITS, Jc as turnName, Ji as emptyIdentityLedger, Jn as pairedMessageFits, Jo as RTC_CONFIG, Jr as mayPin, Js as readSetUpdate, K as groupWakes, Ka as BUTTON_ID, Kc as turnInstance, Ki as IdentityExchange, Kn as LIVENESS_PING_MS, Ko as encodeControl, L as encodeGroupEntryLink, La as queueReaction, Lc as classifyTurnRead, Ln as ENDPOINT, Lr as ChatFiles, Ls as readHandoffAck, M as communityHasFrame, Ma as COMMUNITY_REACTION_FRAME, Mc as seedSigner, Mo as verifyCommitSignature, Mr as rankHubs, Ms as handoffReleaseFrame, N as decodeCommunityLink, Na as GROUP_REACTION_FRAME, Nc as webCryptoSigner, No as edgeParams, Nr as readBeacon, Ns as handoffRetryAfter, O as sealGroupTyping, Oa as dhtEditId, Oc as deviceKeyZ32, Oo as commitHash, Or as mergeBeacon, Os as handoffHelloFrame, P as encodeCommunityLink, Pa as REACTION_LIMITS, Po as DirectPathWatch, Pr as readBeaconHead, Ps as handoffStreamKey, Q as frameBytes, Qc as RelayTransport, Qi as receivedIdentityStatus, Qn as parseEngineError, Qr as readPin, Qs as verifySetUpdate, Qt as didDhtDocument, R as entryParams, Ra as reactionEmoji, Rc as turnPutSummary, Ri as CapsExchange, Rn as cashuRequestPayload, Ro as RELAY_POLL_INTERVALS, Rr as FILE_LIMITS, Rs as readHandoffCancel, S as readAppBundleAsync, Sa as parseVideoMeta, Si as newMailbox, Sn as sparkInvoiceDetails, So as canonicalJson, Sr as beaconKeys, Ss as handoffCancelFrame, T as GroupTypingBoard, Ta as EDIT_BUFFER_MS, Tc as HANDOFF_CAPABILITY, Tl as toZ32, Tn as isPubkyKey, To as GROUP_MEMBER_CAP, Tr as freshHubs, Ts as handoffDataFrame, Tt as isAtprotoDid, Ua as pairedReplyAuthor, Uc as readTurnPacket, Un as parseFedimintRequestPayload, Uo as webLocalFetch, Ur as TypingSender, Us as readHandoffTurnFrame, V as mergeKnocks, Va as validReactionNumber, Vc as firstDeviceSetSecret, Vi as dialDescriptors, Vn as isFederationId, Vo as formatLocalTarget, Vs as readHandoffHello, W as GroupWakeLimiter, Wa as readReply, Wc as signTurnPacket, Wi as IDENTITY_REVOCATION_LABEL, Wn as GhostLink, Wo as LIMITS, Ws as readHandoffVerified, X as GROUP_READ_NOTE, Xc as turnVerifierMark, Xi as identityStatement, Xn as engineError, Xr as pinIsNewer, Xs as setUpdateFrame, Yc as turnStatedVerifier, Yi as identityRevocationValue, Yn as pairedMessageFrame, Yr as nextPinNumber, Ys as setAckFrame, Z as GroupSession, Za as STATUS_CARD_LIMITS, Zc as DEFAULT_RELAYS, Zi as newIdentityBinding, Zn as engineText, Zr as pinNumberHolds, Zs as signTombstone, _c as createChatInvite, _i as HOLD_DATED_BACK_MS, _n as validatePaymentTarget, _o as isAppRef, _r as MESH_HUBS, _s as filePartName, a as planAppUpdate, aa as automaticTransport, ac as enrollDigits, ai as wakeRequest, al as withRequestOptions, an as EVM_TEST_CHAINS, ao as arrivalKey, as as serviceIdFromName, at as groupName, b as pacer, ba as parseVoiceMeta, bi as HoldRefusedError, bl as bytesEqual, bn as SPARK_PROVIDER, br as pickMeshHubs, bs as handoffAttemptSucceeded, cc as enrollHelloFrame, cl as createRelayPayload, cn as SEPOLIA_TEST_USDT, co as receivedTimestamp, cs as HANDOFF_DONE, d as APP_BUNDLE_LIMITS, da as DHT_FILE_CAPABILITY, dc as readEnrollHello, di as APPS_CAPABILITY, dn as USDT_PUBLIC_RPC, do as APP_STATEMENT_LIMITS, ds as HANDOFF_OFFER, ea as lastSharedWithMe, ei as WakeLimiter, el as normalizeRelayUrl, en as encodeDidDhtDeactivated, es as parseCallSignal, f as APP_BUNDLE_MAGIC, fa as dhtFileId, fc as verifyEnrollProof, fi as BUTTONS_CAPABILITY, fl as createIdentity, fn as WALLET_NETWORKS, fo as appFingerprint, fs as HANDOFF_PAKE, g as appViewOf, gc as OwnInviteError, gi as HOLD_CAPABILITY, gl as verify, gn as formatPaymentAmount, go as isAppKey, gr as readGroupSignal, gs as HANDOFF_VERIFIED, h as appDigest, ha as sanitizeMime, hc as readDeviceInvite, hi as UPGRADE_CAPABILITY, hl as publicKeyFromZ32, hn as assertWholeSats, ho as isAppHash, hr as groupSignalFrame, hs as HANDOFF_TIMINGS, i as checkAppBeforeRun, ia as TRANSPORTS, ic as enrollCancelReason, ii as relayRequest, il as isDiscoveryBudgetError, in as ETHEREUM_USDT, io as statusCardText, ir as groupFileFallback, is as LEGACY_SERVICES, it as mentionsMember, j as GROUP_READ_NOTE_COMMUNITY, ja as readForwarded, jc as newDeviceSetSecret, jo as rosterHas, jr as pickHubs, js as handoffPakeFrame, k as COMMUNITY_LIMITS, ka as parseLinkPreview, kc as deviceLinkPairing, ko as parseGroupCommit, kr as mergeLobby, ks as handoffManifestFrames, l as readAppStoreSteps, la as DHT_MESSAGE_TTL, lc as enrollProofFrame, li as chatAppId, lo as shownTime, ls as HANDOFF_HAVE, ma as sanitizeFileName, mc as deviceInviteJoinerParams, mi as STATUS_CARD_CAPABILITY, ml as identityFromSeedB64, mn as assertTokenUnits, ms as HANDOFF_REQUEST, n as appStoreDecision, na as emptyProofLedger, ni as newWakeToken, nl as traceLink, no as checkStatusCard, ns as emptyLinkRecords, nt as carryMentions, o as APP_STORE_LIMITS, oc as enrollDoneFrame, oi as checkPushEndpoint, ol as PacketTooLargeError, on as ONCHAIN_PROVIDER, oo as claimedTime, or as readGroupFileMeta, os as HANDOFF_ACK, p as APP_ICON_PATH, pa as formatFileSize, pc as createDeviceInvite, pi as EDIT_CAPABILITY, pl as identityFromSeed, pn as arkAddressPrefix, po as appRef, ps as HANDOFF_PIECE_BYTES, q as parseGroupWakeFrame, qc as turnKeys, qn as PAIRED_FRAME_TOO_LARGE, qr as PIN_LIMITS, r as appUpdateDecision, ra as validExternalKey, rc as enrollCancelFrame, ri as parseWakeFrame, rl as budgetRetryMs, rn as signDidDhtPacket, ro as sameButtonText, rs as HTTP_SERVICE_PROTO, rt as parseCommunityEdit, sc as enrollGrantFrame, si as vapidKeysMatch, sn as PaymentPreflightError, so as heardTime, ss as HANDOFF_CANCEL, t as appRevocationFor, ta as PeerProofs, ti as deviceWakeRequest, tn as encodeDidDhtPacket, tt as GROUP_EDIT_TEXT_BYTES, ua as peekDhtMailbox, uc as readEnrollGrant, ui as isAppVersion, un as TEST_USDT_FAUCET_AMOUNT, ur as CarriedTransport, us as HANDOFF_HELLO, vc as decodeInviteCode, vi as HOLD_LIMITS, vl as sanitizeAvatar, vn as walletNetworkOf, vo as readAppRevocation, vr as mayBeHub, vs as handoffAttemptAllowed, wc as ENROLL_CAPABILITY, wl as toBase64Url, wo as readCanonicalJson, wr as doorHubs, ws as handoffContextProof, xc as inviteOwnership, xi as isHoldUrl, xl as fromBase64Url, xn as sparkAddressKind, xr as COMMUNITY_TOPOLOGY, xs as handoffBusyFrame, y as isAppUrl, ya as fileMessageText, yc as encodeInviteCode, yi as HoldKeys, yl as sanitizeDisplayText, yn as SPARK_NETWORKS, yr as meshHubs, ys as handoffAttemptFailed, z as knockIdentity, za as reactionIsNewer, zc as TURN_LAST_SEQUENCE, zi as DHT_TEXT_CAPABILITY, zn as fedimintRequestPayload, zo as presenceSeenAt, zr as transferEnded, zs as readHandoffDone } from "./src-CVYir6mP.js";
|
|
3
3
|
import { i as SourceUnreachableError, n as PROVIDER_PLATFORMS, o as isNothingSpentError, r as SourceConfigError, t as NothingSpentError, u as redact } from "./types-C4_KafL_.js";
|
|
4
4
|
import { t as bitcoindRpc } from "./bitcoindProvider-DGw3xBSa.js";
|
|
5
|
-
import { t as nwc } from "./nwcProvider-
|
|
5
|
+
import { t as nwc } from "./nwcProvider-BVVFfJM5.js";
|
|
6
6
|
import { a as clearProfileStores, c as fileStore, d as profileOpenFailure, f as store, i as STORES$1, l as newestWalletTx, m as wrap, n as APP_STORAGE_SCOPE_INDEX, o as databaseName, p as transact, r as CARD_INDEX, s as deleteDatabase, t as APP_STORAGE_CHAT_INDEX, u as openDb } from "./idb-B5L8wuOm.js";
|
|
7
|
-
import { a as sealSeed, i as newDeviceKey, o as unsealSeed, r as intentRepository } from "./networkReason-
|
|
8
|
-
import { $ as setSingleWriterGate, A as LightningCards, B as breezDatabaseInUse, C as FileAppender, D as streamStored, E as storedSize, F as ProviderSources, G as ModeChanged, H as dropBreezDatabase, I as sourceKey, J as networkLabel, K as ModeGate, L as CASHU_MINT_SOURCE, M as isRecoveryPhrase, N as normalizePhrase, P as lightningPaying, Q as setAwayWallets, R as cashuMint, S as WALLET_TYPES, T as removeStored, U as iceServerProblem, V as breezDatabasesFor, W as iceServerSetting, X as refuseAway, Y as awayFrom, Z as requireTurn, _ as crossNetwork, a as storedGroupFiles, b as walletInstances, c as receivedPairedReply, d as paymentAlias, f as paymentWireId, g as createTiming, h as createFailure, i as groupOfFile, j as cardsKey, k as CASHU_CARD, l as replyRef, m as assertConfirmedReal, n as groupFileId, o as groupReply, p as WALLET_NAMES, q as WrongNetworkError, r as groupFileText, s as pairedWireReply, t as GroupFileDesk, u as replyTo, v as paymentNetwork, w as readStored$1, y as paymentNetworksOf, z as breezDatabase } from "./groupFiles-
|
|
9
|
-
import { i as fedimintDatabase, n as createIrohWebEndpoint, o as loadFedimintSdk, r as irohRelayProblem, t as DEFAULT_IROH_RELAYS } from "./irohWeb-
|
|
7
|
+
import { a as sealSeed, i as newDeviceKey, o as unsealSeed, r as intentRepository } from "./networkReason-CrrB031Y.js";
|
|
8
|
+
import { $ as setSingleWriterGate, A as LightningCards, B as breezDatabaseInUse, C as FileAppender, D as streamStored, E as storedSize, F as ProviderSources, G as ModeChanged, H as dropBreezDatabase, I as sourceKey, J as networkLabel, K as ModeGate, L as CASHU_MINT_SOURCE, M as isRecoveryPhrase, N as normalizePhrase, P as lightningPaying, Q as setAwayWallets, R as cashuMint, S as WALLET_TYPES, T as removeStored, U as iceServerProblem, V as breezDatabasesFor, W as iceServerSetting, X as refuseAway, Y as awayFrom, Z as requireTurn, _ as crossNetwork, a as storedGroupFiles, b as walletInstances, c as receivedPairedReply, d as paymentAlias, f as paymentWireId, g as createTiming, h as createFailure, i as groupOfFile, j as cardsKey, k as CASHU_CARD, l as replyRef, m as assertConfirmedReal, n as groupFileId, o as groupReply, p as WALLET_NAMES, q as WrongNetworkError, r as groupFileText, s as pairedWireReply, t as GroupFileDesk, u as replyTo, v as paymentNetwork, w as readStored$1, y as paymentNetworksOf, z as breezDatabase } from "./groupFiles-CqrujNN1.js";
|
|
9
|
+
import { i as fedimintDatabase, n as createIrohWebEndpoint, o as loadFedimintSdk, r as irohRelayProblem, t as DEFAULT_IROH_RELAYS } from "./irohWeb-C8iKFl8d.js";
|
|
10
10
|
import { c as isTestMint, d as paysItsOwnInvoices, l as isWorthlessMint, n as DEFAULT_MINTS, o as fakesLightning, r as TEST_MINT, t as BITCOIN_INVOICE_ON_TESTNET, u as mintNetwork } from "./mints-BrlY773j.js";
|
|
11
|
-
import { _ as reserveAdapterIds, b as testBuild, f as setOwnDidSource, g as registeredOnchainProviders, h as registeredLightningProviders, l as chosenResolver, n as resolveAtprotoDid, p as onAdaptersChanged, t as assertPublicServer, v as boundedIdentityFetch, y as verifyIdentity } from "./resolve-
|
|
11
|
+
import { _ as reserveAdapterIds, b as testBuild, f as setOwnDidSource, g as registeredOnchainProviders, h as registeredLightningProviders, l as chosenResolver, n as resolveAtprotoDid, p as onAdaptersChanged, t as assertPublicServer, v as boundedIdentityFetch, y as verifyIdentity } from "./resolve-DKGaPeMz.js";
|
|
12
12
|
import { c as fileSpace, f as FILE_BYTES_STEP, o as fileBytes, r as blobDigest, s as fileBytesOf, u as removeFileBytes } from "./fileBytes-Di7VZtmU.js";
|
|
13
|
-
import { n as MAX_BACKUP_BYTES, t as BACKUP_MEDIA_TYPE } from "./envelope-
|
|
13
|
+
import { n as MAX_BACKUP_BYTES, t as BACKUP_MEDIA_TYPE } from "./envelope-DHf3mrHv.js";
|
|
14
14
|
import { t as hyperdhtRelayProblem } from "./hyperdhtRelay-BT_wRxab.js";
|
|
15
15
|
import { sha256 } from "@noble/hashes/sha2.js";
|
|
16
16
|
import { hkdf } from "@noble/hashes/hkdf.js";
|
|
@@ -199,7 +199,7 @@ function viewNews(before, after) {
|
|
|
199
199
|
//#endregion
|
|
200
200
|
//#region ../browser/src/engine/paymentAdapters/usdtWallet.ts
|
|
201
201
|
/** The Ethereum libraries, a large part of the app: loaded once a USDT wallet is made, opened or restored, not with the engine. */
|
|
202
|
-
var loadUsdt = () => import("./usdt-
|
|
202
|
+
var loadUsdt = () => import("./usdt-C5Q0BWHr.js");
|
|
203
203
|
/** Every new profile starts with this wallet: an address to receive on, nothing to set up. */
|
|
204
204
|
var DEFAULT_USDT = {
|
|
205
205
|
network: "ethereum",
|
|
@@ -648,7 +648,7 @@ async function restoreArkDatabase(walletId, snapshot) {
|
|
|
648
648
|
//#endregion
|
|
649
649
|
//#region ../browser/src/engine/paymentAdapters/arkWallet.ts
|
|
650
650
|
/** The Ark SDK, a large part of the app: loaded once an Ark wallet is made, opened or restored, not with the engine. */
|
|
651
|
-
var loadArkade = () => import("./arkade-
|
|
651
|
+
var loadArkade = () => import("./arkade-BgmB0fUk.js");
|
|
652
652
|
/** How long a Testnet wallet about to make way for another waits for its server to say what it holds. */
|
|
653
653
|
var RETIRE_READ_MS = 1e4;
|
|
654
654
|
/** Every new profile starts with this wallet: nothing to set up before receiving. */
|
|
@@ -6703,7 +6703,7 @@ var registry;
|
|
|
6703
6703
|
var loading$1;
|
|
6704
6704
|
var listeners = /* @__PURE__ */ new Set();
|
|
6705
6705
|
function loadIdentityProviders() {
|
|
6706
|
-
return loading$1 ??= import("./registry-
|
|
6706
|
+
return loading$1 ??= import("./registry-CshC1EyV.js").then((m) => {
|
|
6707
6707
|
registry = m;
|
|
6708
6708
|
for (const listener of listeners) listener();
|
|
6709
6709
|
return m;
|
|
@@ -23066,7 +23066,11 @@ var Communities = class {
|
|
|
23066
23066
|
g: groupId,
|
|
23067
23067
|
host: s.entryKey
|
|
23068
23068
|
};
|
|
23069
|
-
const
|
|
23069
|
+
const known = [...live.seenHubs.keys()].filter((key) => key !== s.myKey && this.recentHub(live, key) && !this.gone(live, key));
|
|
23070
|
+
const hubs = doorHubs(this.hubs(live), now, s.myKey, {
|
|
23071
|
+
since: live.hubSince,
|
|
23072
|
+
known
|
|
23073
|
+
});
|
|
23070
23074
|
if (!hubs.includes(s.myKey)) return;
|
|
23071
23075
|
const door = [...hubs].sort()[0], doorSig = [...hubs].sort().join(",");
|
|
23072
23076
|
if (live.doors !== doorSig) {
|
|
@@ -43072,7 +43076,7 @@ var GhostlyNode = class GhostlyNode {
|
|
|
43072
43076
|
get nativeFactories() {
|
|
43073
43077
|
const relay = this.relaysHyperdht ? this.hyperdhtRelay : "";
|
|
43074
43078
|
return {
|
|
43075
|
-
...relay ? { "hyperdht/1": async (seedB64) => (await import("./hyperdhtRelay-
|
|
43079
|
+
...relay ? { "hyperdht/1": async (seedB64) => (await import("./hyperdhtRelay-BnqdXvmv.js")).createRelayedHyperEndpoint(seedB64, relay) } : {},
|
|
43076
43080
|
...this.options.nativeTransports,
|
|
43077
43081
|
...this.ownIrohRelays ? { "iroh/1": (seedB64) => this.options.nativeTransports["iroh/1"](seedB64, this.settings.irohRelays?.length ? { relays: [...this.settings.irohRelays] } : {}) } : {},
|
|
43078
43082
|
...this.options.irohWeb ? { "iroh/1": (seedB64) => createIrohWebEndpoint(seedB64, { relays: this.irohRelays }) } : {}
|
|
@@ -43921,4 +43925,4 @@ function signalKind(signal) {
|
|
|
43921
43925
|
//#endregion
|
|
43922
43926
|
export { EngineServer };
|
|
43923
43927
|
|
|
43924
|
-
//# sourceMappingURL=server-
|
|
43928
|
+
//# sourceMappingURL=server-CaDVxJKy.js.map
|