@canton-network/core-splice-client
Advanced tools
+110
-1
@@ -12,3 +12,3 @@ 'use strict'; | ||
| var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
| var ScanClient = class { | ||
| var _ScanClient = class _ScanClient { | ||
| constructor(baseUrl, logger, accessTokenProvider) { | ||
@@ -79,3 +79,112 @@ __publicField(this, "client"); | ||
| } | ||
| async fetchAmuletRulesOnce() { | ||
| const resp = await this.post("/v0/amulet-rules", {}); | ||
| const contract = resp.amulet_rules_update.contract; | ||
| if (!contract?.contract_id || !contract?.template_id) { | ||
| throw new Error("Malformed AmuletRules response"); | ||
| } | ||
| _ScanClient.amuletRulesCache.set(this.baseUrlHref, contract); | ||
| return contract; | ||
| } | ||
| async getAmuletRules() { | ||
| const key = this.baseUrlHref; | ||
| const cached = _ScanClient.amuletRulesCache.get(key); | ||
| if (cached) return structuredClone(cached); | ||
| let inflight = _ScanClient.amuletRulesInflight.get(key); | ||
| if (!inflight) { | ||
| inflight = this.fetchAmuletRulesOnce().finally(() => { | ||
| _ScanClient.amuletRulesInflight.delete(key); | ||
| }); | ||
| _ScanClient.amuletRulesInflight.set(key, inflight); | ||
| } | ||
| const contract = await inflight; | ||
| return structuredClone(contract); | ||
| } | ||
| static invalidateAmuletRulesCache(baseUrl) { | ||
| const key = baseUrl.href; | ||
| this.amuletRulesCache.delete(key); | ||
| this.amuletRulesInflight.delete(key); | ||
| } | ||
| computeNextChangeAt(rounds) { | ||
| const now = Date.now(); | ||
| let next = Number.POSITIVE_INFINITY; | ||
| for (const round of rounds) { | ||
| const { opensAt, targetClosesAt } = round.payload ?? {}; | ||
| const openMs = opensAt ? Number(new Date(opensAt)) : NaN; | ||
| const closeMs = targetClosesAt ? Number(new Date(targetClosesAt)) : NaN; | ||
| if (Number.isFinite(openMs) && openMs > now && openMs < next) { | ||
| next = openMs; | ||
| } | ||
| if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) { | ||
| next = closeMs; | ||
| } | ||
| } | ||
| return Number.isFinite(next) ? next : now; | ||
| } | ||
| async fetchOpenMiningRoundsOnce() { | ||
| const resp = await this.post("/v0/open-and-issuing-mining-rounds", { | ||
| cached_open_mining_round_contract_ids: [], | ||
| cached_issuing_round_contract_ids: [] | ||
| }); | ||
| const rounds = Object.values(resp.open_mining_rounds).flatMap( | ||
| (x) => x.contract ? [x.contract] : [] | ||
| ); | ||
| const key = this.baseUrlHref; | ||
| _ScanClient.roundsCache.set(key, rounds); | ||
| _ScanClient.roundsNextChangeAt.set(key, this.computeNextChangeAt(rounds)); | ||
| return rounds; | ||
| } | ||
| async refreshRounds(key) { | ||
| let inflight = _ScanClient.roundsInflight.get(key); | ||
| if (!inflight) { | ||
| inflight = this.fetchOpenMiningRoundsOnce().finally(() => { | ||
| _ScanClient.roundsInflight.delete(key); | ||
| }); | ||
| _ScanClient.roundsInflight.set(key, inflight); | ||
| } | ||
| return inflight; | ||
| } | ||
| async getOpenMiningRounds() { | ||
| const key = this.baseUrlHref; | ||
| const now = Date.now(); | ||
| const cached = _ScanClient.roundsCache.get(key); | ||
| const next = _ScanClient.roundsNextChangeAt.get(key); | ||
| if (cached && next !== void 0 && now < next) { | ||
| return structuredClone(cached); | ||
| } | ||
| const fresh = await this.refreshRounds(key); | ||
| return structuredClone(fresh); | ||
| } | ||
| async getActiveOpenMiningRound() { | ||
| const pickActive = (rounds2, timestamp) => rounds2.filter((round) => { | ||
| const { opensAt, targetClosesAt } = round.payload; | ||
| const openMs = opensAt ? Number(new Date(opensAt)) : NaN; | ||
| const closeMs = targetClosesAt ? Number(new Date(targetClosesAt)) : NaN; | ||
| return Number.isFinite(openMs) && Number.isFinite(closeMs) && openMs <= timestamp && timestamp < closeMs; | ||
| }).sort((a, b) => a.payload.opensAt - b.payload.opensAt).at(-1) ?? null; | ||
| const now = Date.now(); | ||
| const rounds = await this.getOpenMiningRounds(); | ||
| const active = pickActive(rounds, now); | ||
| return active ? structuredClone(active) : null; | ||
| } | ||
| static invalidateOpenMiningRoundsCache(baseUrl) { | ||
| const key = baseUrl.href; | ||
| this.roundsCache.delete(key); | ||
| this.roundsInflight.delete(key); | ||
| this.roundsNextChangeAt.delete(key); | ||
| } | ||
| async isDevNet() { | ||
| const amuletRules = await this.getAmuletRules(); | ||
| const payload = amuletRules.payload; | ||
| return payload?.isDevNet ?? false; | ||
| } | ||
| }; | ||
| __publicField(_ScanClient, "amuletRulesCache", /* @__PURE__ */ new Map()); | ||
| __publicField(_ScanClient, "roundsCache", /* @__PURE__ */ new Map()); | ||
| // one in-flight fetch per baseUrl for rules/rounds | ||
| __publicField(_ScanClient, "amuletRulesInflight", /* @__PURE__ */ new Map()); | ||
| __publicField(_ScanClient, "roundsInflight", /* @__PURE__ */ new Map()); | ||
| // time after surpassing which mining rounds should be refreshed | ||
| __publicField(_ScanClient, "roundsNextChangeAt", /* @__PURE__ */ new Map()); | ||
| var ScanClient = _ScanClient; | ||
| var _ScanProxyClient = class _ScanProxyClient { | ||
@@ -82,0 +191,0 @@ constructor(baseUrl, logger, accessTokenProvider) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/scan-client.ts","../src/scan-proxy-client.ts","../src/validator-internal-client.ts"],"names":["createClient","rounds"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.logger = logger\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n\n this.logger.debug({ baseUrl }, 'ScanClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n const dsoInfo = await this.get('/v0/dso')\n\n const payloadObj = JSON.parse(\n JSON.stringify(dsoInfo.amulet_rules.contract.payload)\n )\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues as []\n\n if (futureValues.length > 0) {\n let updatedValue = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan-proxy'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanProxyTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanProxyClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n // shared caches for all instances of ScanProxyClient\n private static amuletRulesCache = new Map<\n string,\n ScanProxyTypes['Contract']\n >()\n private static roundsCache = new Map<string, ScanProxyTypes['Contract'][]>()\n // one in-flight fetch per baseUrl for rules/rounds\n private static amuletRulesInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract']>\n >()\n private static roundsInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract'][]>\n >()\n // time after surpassing which mining rounds should be refreshed\n private static roundsNextChangeAt = new Map<string, number>()\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ScanProxyClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n private async fetchAmuletRulesOnce(): Promise<ScanProxyTypes['Contract']> {\n const resp = await this.get('/v0/scan-proxy/amulet-rules')\n const contract = resp?.amulet_rules?.contract\n if (!contract?.contract_id || !contract?.template_id) {\n throw new Error('Malformed AmuletRules response')\n }\n ScanProxyClient.amuletRulesCache.set(this.baseUrlHref, contract)\n return contract\n }\n\n public async getAmuletRules(): Promise<ScanProxyTypes['Contract']> {\n const key = this.baseUrlHref\n\n const cached = ScanProxyClient.amuletRulesCache.get(key)\n // clone to prevent external mutation of cache by object reference\n if (cached) return structuredClone(cached)\n\n let inflight = ScanProxyClient.amuletRulesInflight.get(key)\n if (!inflight) {\n inflight = this.fetchAmuletRulesOnce().finally(() => {\n ScanProxyClient.amuletRulesInflight.delete(key)\n })\n ScanProxyClient.amuletRulesInflight.set(key, inflight)\n }\n\n const contract = await inflight\n return structuredClone(contract)\n }\n\n public static invalidateAmuletRulesCache(baseUrl: URL) {\n const key = baseUrl.href\n this.amuletRulesCache.delete(key)\n this.amuletRulesInflight.delete(key)\n }\n\n private computeNextChangeAt(rounds: ScanProxyTypes['Contract'][]): number {\n const now = Date.now()\n let next = Number.POSITIVE_INFINITY\n\n for (const round of rounds) {\n const { opensAt, targetClosesAt } = round.payload ?? {}\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n\n if (Number.isFinite(openMs) && openMs > now && openMs < next) {\n next = openMs\n }\n if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) {\n next = closeMs\n }\n }\n\n // If we couldn't parse anything sensible, force an immediate refresh.\n return Number.isFinite(next) ? next : now\n }\n\n private async fetchOpenMiningRoundsOnce(): Promise<\n ScanProxyTypes['Contract'][]\n > {\n const resp = await this.get(\n '/v0/scan-proxy/open-and-issuing-mining-rounds'\n )\n const rounds = (resp.open_mining_rounds ?? []).map(\n (x) => x.contract\n ) as ScanProxyTypes['Contract'][]\n\n const key = this.baseUrlHref\n ScanProxyClient.roundsCache.set(key, rounds)\n ScanProxyClient.roundsNextChangeAt.set(\n key,\n this.computeNextChangeAt(rounds)\n )\n return rounds\n }\n\n private async refreshRounds(\n key: string\n ): Promise<ScanProxyTypes['Contract'][]> {\n let inflight = ScanProxyClient.roundsInflight.get(key)\n if (!inflight) {\n inflight = this.fetchOpenMiningRoundsOnce().finally(() => {\n ScanProxyClient.roundsInflight.delete(key)\n })\n ScanProxyClient.roundsInflight.set(key, inflight)\n }\n return inflight\n }\n\n public async getOpenMiningRounds(): Promise<ScanProxyTypes['Contract'][]> {\n const key = this.baseUrlHref\n const now = Date.now()\n const cached = ScanProxyClient.roundsCache.get(key)\n const next = ScanProxyClient.roundsNextChangeAt.get(key)\n\n if (cached && next !== undefined && now < next) {\n return structuredClone(cached)\n }\n const fresh = await this.refreshRounds(key)\n return structuredClone(fresh)\n }\n\n public async getActiveOpenMiningRound(): Promise<\n ScanProxyTypes['Contract'] | null\n > {\n const pickActive = (\n rounds: ScanProxyTypes['Contract'][],\n timestamp: number\n ) =>\n rounds\n .filter((round) => {\n const { opensAt, targetClosesAt } = round.payload\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n return (\n Number.isFinite(openMs) &&\n Number.isFinite(closeMs) &&\n openMs <= timestamp &&\n timestamp < closeMs\n )\n })\n .sort((a, b) => a.payload.opensAt - b.payload.opensAt)\n .at(-1) ?? null\n\n const now = Date.now()\n const rounds = await this.getOpenMiningRounds()\n const active = pickActive(rounds, now)\n return active ? structuredClone(active) : null\n }\n\n public static invalidateOpenMiningRoundsCache(baseUrl: URL) {\n const key = baseUrl.href\n this.roundsCache.delete(key)\n this.roundsInflight.delete(key)\n this.roundsNextChangeAt.delete(key)\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n type FutureValue = {\n decentralizedSynchronizer?: {\n activeSynchronizer?: string\n }\n }\n\n type Payload = {\n configSchedule?: {\n initialValue?: FutureValue\n futureValues?: FutureValue[]\n }\n }\n\n const amuletRules = await this.getAmuletRules()\n const payloadObj = amuletRules.payload as Payload\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues\n\n if (Array.isArray(futureValues) && futureValues.length > 0) {\n let updatedValue: string | undefined = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n\n public async isDevNet(): Promise<boolean> {\n const amuletRules = await this.getAmuletRules()\n const payload = amuletRules.payload as { isDevNet?: boolean }\n return payload?.isDevNet ?? false\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { paths } from './generated-clients/validator-internal'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ValidatorInternalClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private accessTokenProvider: AccessTokenProvider\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ValidatorInternalClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n}\n"]} | ||
| {"version":3,"sources":["../src/scan-client.ts","../src/scan-proxy-client.ts","../src/validator-internal-client.ts"],"names":["createClient","rounds"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n\n private static amuletRulesCache = new Map<string, ScanTypes['Contract']>()\n\n private static roundsCache = new Map<string, ScanTypes['Contract'][]>()\n // one in-flight fetch per baseUrl for rules/rounds\n private static amuletRulesInflight = new Map<\n string,\n Promise<ScanTypes['Contract']>\n >()\n private static roundsInflight = new Map<\n string,\n Promise<ScanTypes['Contract'][]>\n >()\n\n // time after surpassing which mining rounds should be refreshed\n private static roundsNextChangeAt = new Map<string, number>()\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.logger = logger\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n\n this.logger.debug({ baseUrl }, 'ScanClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n const dsoInfo = await this.get('/v0/dso')\n\n const payloadObj = JSON.parse(\n JSON.stringify(dsoInfo.amulet_rules.contract.payload)\n )\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues as []\n\n if (futureValues.length > 0) {\n let updatedValue = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n\n private async fetchAmuletRulesOnce(): Promise<ScanTypes['Contract']> {\n const resp = await this.post('/v0/amulet-rules', {})\n const contract = resp.amulet_rules_update.contract\n if (!contract?.contract_id || !contract?.template_id) {\n throw new Error('Malformed AmuletRules response')\n }\n ScanClient.amuletRulesCache.set(this.baseUrlHref, contract)\n return contract\n }\n\n public async getAmuletRules(): Promise<ScanTypes['Contract']> {\n const key = this.baseUrlHref\n\n const cached = ScanClient.amuletRulesCache.get(key)\n // clone to prevent external mutation of cache by object reference\n if (cached) return structuredClone(cached)\n\n let inflight = ScanClient.amuletRulesInflight.get(key)\n if (!inflight) {\n inflight = this.fetchAmuletRulesOnce().finally(() => {\n ScanClient.amuletRulesInflight.delete(key)\n })\n ScanClient.amuletRulesInflight.set(key, inflight)\n }\n\n const contract = await inflight\n return structuredClone(contract)\n }\n\n public static invalidateAmuletRulesCache(baseUrl: URL) {\n const key = baseUrl.href\n this.amuletRulesCache.delete(key)\n this.amuletRulesInflight.delete(key)\n }\n\n private computeNextChangeAt(rounds: ScanTypes['Contract'][]): number {\n const now = Date.now()\n let next = Number.POSITIVE_INFINITY\n\n for (const round of rounds) {\n const { opensAt, targetClosesAt } = round.payload ?? {}\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n\n if (Number.isFinite(openMs) && openMs > now && openMs < next) {\n next = openMs\n }\n if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) {\n next = closeMs\n }\n }\n\n // If we couldn't parse anything sensible, force an immediate refresh.\n return Number.isFinite(next) ? next : now\n }\n\n private async fetchOpenMiningRoundsOnce(): Promise<\n ScanTypes['Contract'][]\n > {\n const resp = await this.post('/v0/open-and-issuing-mining-rounds', {\n cached_open_mining_round_contract_ids: [],\n cached_issuing_round_contract_ids: [],\n })\n\n const rounds = Object.values(resp.open_mining_rounds).flatMap((x) =>\n x.contract ? [x.contract] : []\n )\n\n const key = this.baseUrlHref\n ScanClient.roundsCache.set(key, rounds)\n ScanClient.roundsNextChangeAt.set(key, this.computeNextChangeAt(rounds))\n return rounds\n }\n\n private async refreshRounds(key: string): Promise<ScanTypes['Contract'][]> {\n let inflight = ScanClient.roundsInflight.get(key)\n if (!inflight) {\n inflight = this.fetchOpenMiningRoundsOnce().finally(() => {\n ScanClient.roundsInflight.delete(key)\n })\n ScanClient.roundsInflight.set(key, inflight)\n }\n return inflight\n }\n\n public async getOpenMiningRounds(): Promise<ScanTypes['Contract'][]> {\n const key = this.baseUrlHref\n const now = Date.now()\n const cached = ScanClient.roundsCache.get(key)\n const next = ScanClient.roundsNextChangeAt.get(key)\n\n if (cached && next !== undefined && now < next) {\n return structuredClone(cached)\n }\n const fresh = await this.refreshRounds(key)\n return structuredClone(fresh)\n }\n\n public async getActiveOpenMiningRound(): Promise<\n ScanTypes['Contract'] | null\n > {\n const pickActive = (\n rounds: ScanTypes['Contract'][],\n timestamp: number\n ) =>\n rounds\n .filter((round) => {\n const { opensAt, targetClosesAt } = round.payload\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n return (\n Number.isFinite(openMs) &&\n Number.isFinite(closeMs) &&\n openMs <= timestamp &&\n timestamp < closeMs\n )\n })\n .sort((a, b) => a.payload.opensAt - b.payload.opensAt)\n .at(-1) ?? null\n\n const now = Date.now()\n const rounds = await this.getOpenMiningRounds()\n const active = pickActive(rounds, now)\n return active ? structuredClone(active) : null\n }\n\n public static invalidateOpenMiningRoundsCache(baseUrl: URL) {\n const key = baseUrl.href\n this.roundsCache.delete(key)\n this.roundsInflight.delete(key)\n this.roundsNextChangeAt.delete(key)\n }\n\n public async isDevNet(): Promise<boolean> {\n const amuletRules = await this.getAmuletRules()\n const payload = amuletRules.payload as { isDevNet?: boolean }\n return payload?.isDevNet ?? false\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan-proxy'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanProxyTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanProxyClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n // shared caches for all instances of ScanProxyClient\n private static amuletRulesCache = new Map<\n string,\n ScanProxyTypes['Contract']\n >()\n private static roundsCache = new Map<string, ScanProxyTypes['Contract'][]>()\n // one in-flight fetch per baseUrl for rules/rounds\n private static amuletRulesInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract']>\n >()\n private static roundsInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract'][]>\n >()\n // time after surpassing which mining rounds should be refreshed\n private static roundsNextChangeAt = new Map<string, number>()\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ScanProxyClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n private async fetchAmuletRulesOnce(): Promise<ScanProxyTypes['Contract']> {\n const resp = await this.get('/v0/scan-proxy/amulet-rules')\n const contract = resp?.amulet_rules?.contract\n if (!contract?.contract_id || !contract?.template_id) {\n throw new Error('Malformed AmuletRules response')\n }\n ScanProxyClient.amuletRulesCache.set(this.baseUrlHref, contract)\n return contract\n }\n\n public async getAmuletRules(): Promise<ScanProxyTypes['Contract']> {\n const key = this.baseUrlHref\n\n const cached = ScanProxyClient.amuletRulesCache.get(key)\n // clone to prevent external mutation of cache by object reference\n if (cached) return structuredClone(cached)\n\n let inflight = ScanProxyClient.amuletRulesInflight.get(key)\n if (!inflight) {\n inflight = this.fetchAmuletRulesOnce().finally(() => {\n ScanProxyClient.amuletRulesInflight.delete(key)\n })\n ScanProxyClient.amuletRulesInflight.set(key, inflight)\n }\n\n const contract = await inflight\n return structuredClone(contract)\n }\n\n public static invalidateAmuletRulesCache(baseUrl: URL) {\n const key = baseUrl.href\n this.amuletRulesCache.delete(key)\n this.amuletRulesInflight.delete(key)\n }\n\n private computeNextChangeAt(rounds: ScanProxyTypes['Contract'][]): number {\n const now = Date.now()\n let next = Number.POSITIVE_INFINITY\n\n for (const round of rounds) {\n const { opensAt, targetClosesAt } = round.payload ?? {}\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n\n if (Number.isFinite(openMs) && openMs > now && openMs < next) {\n next = openMs\n }\n if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) {\n next = closeMs\n }\n }\n\n // If we couldn't parse anything sensible, force an immediate refresh.\n return Number.isFinite(next) ? next : now\n }\n\n private async fetchOpenMiningRoundsOnce(): Promise<\n ScanProxyTypes['Contract'][]\n > {\n const resp = await this.get(\n '/v0/scan-proxy/open-and-issuing-mining-rounds'\n )\n const rounds = (resp.open_mining_rounds ?? []).map(\n (x) => x.contract\n ) as ScanProxyTypes['Contract'][]\n\n const key = this.baseUrlHref\n ScanProxyClient.roundsCache.set(key, rounds)\n ScanProxyClient.roundsNextChangeAt.set(\n key,\n this.computeNextChangeAt(rounds)\n )\n return rounds\n }\n\n private async refreshRounds(\n key: string\n ): Promise<ScanProxyTypes['Contract'][]> {\n let inflight = ScanProxyClient.roundsInflight.get(key)\n if (!inflight) {\n inflight = this.fetchOpenMiningRoundsOnce().finally(() => {\n ScanProxyClient.roundsInflight.delete(key)\n })\n ScanProxyClient.roundsInflight.set(key, inflight)\n }\n return inflight\n }\n\n public async getOpenMiningRounds(): Promise<ScanProxyTypes['Contract'][]> {\n const key = this.baseUrlHref\n const now = Date.now()\n const cached = ScanProxyClient.roundsCache.get(key)\n const next = ScanProxyClient.roundsNextChangeAt.get(key)\n\n if (cached && next !== undefined && now < next) {\n return structuredClone(cached)\n }\n const fresh = await this.refreshRounds(key)\n return structuredClone(fresh)\n }\n\n public async getActiveOpenMiningRound(): Promise<\n ScanProxyTypes['Contract'] | null\n > {\n const pickActive = (\n rounds: ScanProxyTypes['Contract'][],\n timestamp: number\n ) =>\n rounds\n .filter((round) => {\n const { opensAt, targetClosesAt } = round.payload\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n return (\n Number.isFinite(openMs) &&\n Number.isFinite(closeMs) &&\n openMs <= timestamp &&\n timestamp < closeMs\n )\n })\n .sort((a, b) => a.payload.opensAt - b.payload.opensAt)\n .at(-1) ?? null\n\n const now = Date.now()\n const rounds = await this.getOpenMiningRounds()\n const active = pickActive(rounds, now)\n return active ? structuredClone(active) : null\n }\n\n public static invalidateOpenMiningRoundsCache(baseUrl: URL) {\n const key = baseUrl.href\n this.roundsCache.delete(key)\n this.roundsInflight.delete(key)\n this.roundsNextChangeAt.delete(key)\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n type FutureValue = {\n decentralizedSynchronizer?: {\n activeSynchronizer?: string\n }\n }\n\n type Payload = {\n configSchedule?: {\n initialValue?: FutureValue\n futureValues?: FutureValue[]\n }\n }\n\n const amuletRules = await this.getAmuletRules()\n const payloadObj = amuletRules.payload as Payload\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues\n\n if (Array.isArray(futureValues) && futureValues.length > 0) {\n let updatedValue: string | undefined = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n\n public async isDevNet(): Promise<boolean> {\n const amuletRules = await this.getAmuletRules()\n const payload = amuletRules.payload as { isDevNet?: boolean }\n return payload?.isDevNet ?? false\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { paths } from './generated-clients/validator-internal'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ValidatorInternalClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private accessTokenProvider: AccessTokenProvider\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ValidatorInternalClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n}\n"]} |
+110
-1
@@ -6,3 +6,3 @@ import createClient from 'openapi-fetch'; | ||
| var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
| var ScanClient = class { | ||
| var _ScanClient = class _ScanClient { | ||
| constructor(baseUrl, logger, accessTokenProvider) { | ||
@@ -73,3 +73,112 @@ __publicField(this, "client"); | ||
| } | ||
| async fetchAmuletRulesOnce() { | ||
| const resp = await this.post("/v0/amulet-rules", {}); | ||
| const contract = resp.amulet_rules_update.contract; | ||
| if (!contract?.contract_id || !contract?.template_id) { | ||
| throw new Error("Malformed AmuletRules response"); | ||
| } | ||
| _ScanClient.amuletRulesCache.set(this.baseUrlHref, contract); | ||
| return contract; | ||
| } | ||
| async getAmuletRules() { | ||
| const key = this.baseUrlHref; | ||
| const cached = _ScanClient.amuletRulesCache.get(key); | ||
| if (cached) return structuredClone(cached); | ||
| let inflight = _ScanClient.amuletRulesInflight.get(key); | ||
| if (!inflight) { | ||
| inflight = this.fetchAmuletRulesOnce().finally(() => { | ||
| _ScanClient.amuletRulesInflight.delete(key); | ||
| }); | ||
| _ScanClient.amuletRulesInflight.set(key, inflight); | ||
| } | ||
| const contract = await inflight; | ||
| return structuredClone(contract); | ||
| } | ||
| static invalidateAmuletRulesCache(baseUrl) { | ||
| const key = baseUrl.href; | ||
| this.amuletRulesCache.delete(key); | ||
| this.amuletRulesInflight.delete(key); | ||
| } | ||
| computeNextChangeAt(rounds) { | ||
| const now = Date.now(); | ||
| let next = Number.POSITIVE_INFINITY; | ||
| for (const round of rounds) { | ||
| const { opensAt, targetClosesAt } = round.payload ?? {}; | ||
| const openMs = opensAt ? Number(new Date(opensAt)) : NaN; | ||
| const closeMs = targetClosesAt ? Number(new Date(targetClosesAt)) : NaN; | ||
| if (Number.isFinite(openMs) && openMs > now && openMs < next) { | ||
| next = openMs; | ||
| } | ||
| if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) { | ||
| next = closeMs; | ||
| } | ||
| } | ||
| return Number.isFinite(next) ? next : now; | ||
| } | ||
| async fetchOpenMiningRoundsOnce() { | ||
| const resp = await this.post("/v0/open-and-issuing-mining-rounds", { | ||
| cached_open_mining_round_contract_ids: [], | ||
| cached_issuing_round_contract_ids: [] | ||
| }); | ||
| const rounds = Object.values(resp.open_mining_rounds).flatMap( | ||
| (x) => x.contract ? [x.contract] : [] | ||
| ); | ||
| const key = this.baseUrlHref; | ||
| _ScanClient.roundsCache.set(key, rounds); | ||
| _ScanClient.roundsNextChangeAt.set(key, this.computeNextChangeAt(rounds)); | ||
| return rounds; | ||
| } | ||
| async refreshRounds(key) { | ||
| let inflight = _ScanClient.roundsInflight.get(key); | ||
| if (!inflight) { | ||
| inflight = this.fetchOpenMiningRoundsOnce().finally(() => { | ||
| _ScanClient.roundsInflight.delete(key); | ||
| }); | ||
| _ScanClient.roundsInflight.set(key, inflight); | ||
| } | ||
| return inflight; | ||
| } | ||
| async getOpenMiningRounds() { | ||
| const key = this.baseUrlHref; | ||
| const now = Date.now(); | ||
| const cached = _ScanClient.roundsCache.get(key); | ||
| const next = _ScanClient.roundsNextChangeAt.get(key); | ||
| if (cached && next !== void 0 && now < next) { | ||
| return structuredClone(cached); | ||
| } | ||
| const fresh = await this.refreshRounds(key); | ||
| return structuredClone(fresh); | ||
| } | ||
| async getActiveOpenMiningRound() { | ||
| const pickActive = (rounds2, timestamp) => rounds2.filter((round) => { | ||
| const { opensAt, targetClosesAt } = round.payload; | ||
| const openMs = opensAt ? Number(new Date(opensAt)) : NaN; | ||
| const closeMs = targetClosesAt ? Number(new Date(targetClosesAt)) : NaN; | ||
| return Number.isFinite(openMs) && Number.isFinite(closeMs) && openMs <= timestamp && timestamp < closeMs; | ||
| }).sort((a, b) => a.payload.opensAt - b.payload.opensAt).at(-1) ?? null; | ||
| const now = Date.now(); | ||
| const rounds = await this.getOpenMiningRounds(); | ||
| const active = pickActive(rounds, now); | ||
| return active ? structuredClone(active) : null; | ||
| } | ||
| static invalidateOpenMiningRoundsCache(baseUrl) { | ||
| const key = baseUrl.href; | ||
| this.roundsCache.delete(key); | ||
| this.roundsInflight.delete(key); | ||
| this.roundsNextChangeAt.delete(key); | ||
| } | ||
| async isDevNet() { | ||
| const amuletRules = await this.getAmuletRules(); | ||
| const payload = amuletRules.payload; | ||
| return payload?.isDevNet ?? false; | ||
| } | ||
| }; | ||
| __publicField(_ScanClient, "amuletRulesCache", /* @__PURE__ */ new Map()); | ||
| __publicField(_ScanClient, "roundsCache", /* @__PURE__ */ new Map()); | ||
| // one in-flight fetch per baseUrl for rules/rounds | ||
| __publicField(_ScanClient, "amuletRulesInflight", /* @__PURE__ */ new Map()); | ||
| __publicField(_ScanClient, "roundsInflight", /* @__PURE__ */ new Map()); | ||
| // time after surpassing which mining rounds should be refreshed | ||
| __publicField(_ScanClient, "roundsNextChangeAt", /* @__PURE__ */ new Map()); | ||
| var ScanClient = _ScanClient; | ||
| var _ScanProxyClient = class _ScanProxyClient { | ||
@@ -76,0 +185,0 @@ constructor(baseUrl, logger, accessTokenProvider) { |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/scan-client.ts","../src/scan-proxy-client.ts","../src/validator-internal-client.ts"],"names":["createClient","rounds"],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.logger = logger\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n\n this.logger.debug({ baseUrl }, 'ScanClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n const dsoInfo = await this.get('/v0/dso')\n\n const payloadObj = JSON.parse(\n JSON.stringify(dsoInfo.amulet_rules.contract.payload)\n )\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues as []\n\n if (futureValues.length > 0) {\n let updatedValue = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan-proxy'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanProxyTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanProxyClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n // shared caches for all instances of ScanProxyClient\n private static amuletRulesCache = new Map<\n string,\n ScanProxyTypes['Contract']\n >()\n private static roundsCache = new Map<string, ScanProxyTypes['Contract'][]>()\n // one in-flight fetch per baseUrl for rules/rounds\n private static amuletRulesInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract']>\n >()\n private static roundsInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract'][]>\n >()\n // time after surpassing which mining rounds should be refreshed\n private static roundsNextChangeAt = new Map<string, number>()\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ScanProxyClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n private async fetchAmuletRulesOnce(): Promise<ScanProxyTypes['Contract']> {\n const resp = await this.get('/v0/scan-proxy/amulet-rules')\n const contract = resp?.amulet_rules?.contract\n if (!contract?.contract_id || !contract?.template_id) {\n throw new Error('Malformed AmuletRules response')\n }\n ScanProxyClient.amuletRulesCache.set(this.baseUrlHref, contract)\n return contract\n }\n\n public async getAmuletRules(): Promise<ScanProxyTypes['Contract']> {\n const key = this.baseUrlHref\n\n const cached = ScanProxyClient.amuletRulesCache.get(key)\n // clone to prevent external mutation of cache by object reference\n if (cached) return structuredClone(cached)\n\n let inflight = ScanProxyClient.amuletRulesInflight.get(key)\n if (!inflight) {\n inflight = this.fetchAmuletRulesOnce().finally(() => {\n ScanProxyClient.amuletRulesInflight.delete(key)\n })\n ScanProxyClient.amuletRulesInflight.set(key, inflight)\n }\n\n const contract = await inflight\n return structuredClone(contract)\n }\n\n public static invalidateAmuletRulesCache(baseUrl: URL) {\n const key = baseUrl.href\n this.amuletRulesCache.delete(key)\n this.amuletRulesInflight.delete(key)\n }\n\n private computeNextChangeAt(rounds: ScanProxyTypes['Contract'][]): number {\n const now = Date.now()\n let next = Number.POSITIVE_INFINITY\n\n for (const round of rounds) {\n const { opensAt, targetClosesAt } = round.payload ?? {}\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n\n if (Number.isFinite(openMs) && openMs > now && openMs < next) {\n next = openMs\n }\n if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) {\n next = closeMs\n }\n }\n\n // If we couldn't parse anything sensible, force an immediate refresh.\n return Number.isFinite(next) ? next : now\n }\n\n private async fetchOpenMiningRoundsOnce(): Promise<\n ScanProxyTypes['Contract'][]\n > {\n const resp = await this.get(\n '/v0/scan-proxy/open-and-issuing-mining-rounds'\n )\n const rounds = (resp.open_mining_rounds ?? []).map(\n (x) => x.contract\n ) as ScanProxyTypes['Contract'][]\n\n const key = this.baseUrlHref\n ScanProxyClient.roundsCache.set(key, rounds)\n ScanProxyClient.roundsNextChangeAt.set(\n key,\n this.computeNextChangeAt(rounds)\n )\n return rounds\n }\n\n private async refreshRounds(\n key: string\n ): Promise<ScanProxyTypes['Contract'][]> {\n let inflight = ScanProxyClient.roundsInflight.get(key)\n if (!inflight) {\n inflight = this.fetchOpenMiningRoundsOnce().finally(() => {\n ScanProxyClient.roundsInflight.delete(key)\n })\n ScanProxyClient.roundsInflight.set(key, inflight)\n }\n return inflight\n }\n\n public async getOpenMiningRounds(): Promise<ScanProxyTypes['Contract'][]> {\n const key = this.baseUrlHref\n const now = Date.now()\n const cached = ScanProxyClient.roundsCache.get(key)\n const next = ScanProxyClient.roundsNextChangeAt.get(key)\n\n if (cached && next !== undefined && now < next) {\n return structuredClone(cached)\n }\n const fresh = await this.refreshRounds(key)\n return structuredClone(fresh)\n }\n\n public async getActiveOpenMiningRound(): Promise<\n ScanProxyTypes['Contract'] | null\n > {\n const pickActive = (\n rounds: ScanProxyTypes['Contract'][],\n timestamp: number\n ) =>\n rounds\n .filter((round) => {\n const { opensAt, targetClosesAt } = round.payload\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n return (\n Number.isFinite(openMs) &&\n Number.isFinite(closeMs) &&\n openMs <= timestamp &&\n timestamp < closeMs\n )\n })\n .sort((a, b) => a.payload.opensAt - b.payload.opensAt)\n .at(-1) ?? null\n\n const now = Date.now()\n const rounds = await this.getOpenMiningRounds()\n const active = pickActive(rounds, now)\n return active ? structuredClone(active) : null\n }\n\n public static invalidateOpenMiningRoundsCache(baseUrl: URL) {\n const key = baseUrl.href\n this.roundsCache.delete(key)\n this.roundsInflight.delete(key)\n this.roundsNextChangeAt.delete(key)\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n type FutureValue = {\n decentralizedSynchronizer?: {\n activeSynchronizer?: string\n }\n }\n\n type Payload = {\n configSchedule?: {\n initialValue?: FutureValue\n futureValues?: FutureValue[]\n }\n }\n\n const amuletRules = await this.getAmuletRules()\n const payloadObj = amuletRules.payload as Payload\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues\n\n if (Array.isArray(futureValues) && futureValues.length > 0) {\n let updatedValue: string | undefined = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n\n public async isDevNet(): Promise<boolean> {\n const amuletRules = await this.getAmuletRules()\n const payload = amuletRules.payload as { isDevNet?: boolean }\n return payload?.isDevNet ?? false\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { paths } from './generated-clients/validator-internal'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ValidatorInternalClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private accessTokenProvider: AccessTokenProvider\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ValidatorInternalClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n}\n"]} | ||
| {"version":3,"sources":["../src/scan-client.ts","../src/scan-proxy-client.ts","../src/validator-internal-client.ts"],"names":["rounds","createClient"],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n\n private static amuletRulesCache = new Map<string, ScanTypes['Contract']>()\n\n private static roundsCache = new Map<string, ScanTypes['Contract'][]>()\n // one in-flight fetch per baseUrl for rules/rounds\n private static amuletRulesInflight = new Map<\n string,\n Promise<ScanTypes['Contract']>\n >()\n private static roundsInflight = new Map<\n string,\n Promise<ScanTypes['Contract'][]>\n >()\n\n // time after surpassing which mining rounds should be refreshed\n private static roundsNextChangeAt = new Map<string, number>()\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.logger = logger\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n\n this.logger.debug({ baseUrl }, 'ScanClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n const dsoInfo = await this.get('/v0/dso')\n\n const payloadObj = JSON.parse(\n JSON.stringify(dsoInfo.amulet_rules.contract.payload)\n )\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues as []\n\n if (futureValues.length > 0) {\n let updatedValue = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n\n private async fetchAmuletRulesOnce(): Promise<ScanTypes['Contract']> {\n const resp = await this.post('/v0/amulet-rules', {})\n const contract = resp.amulet_rules_update.contract\n if (!contract?.contract_id || !contract?.template_id) {\n throw new Error('Malformed AmuletRules response')\n }\n ScanClient.amuletRulesCache.set(this.baseUrlHref, contract)\n return contract\n }\n\n public async getAmuletRules(): Promise<ScanTypes['Contract']> {\n const key = this.baseUrlHref\n\n const cached = ScanClient.amuletRulesCache.get(key)\n // clone to prevent external mutation of cache by object reference\n if (cached) return structuredClone(cached)\n\n let inflight = ScanClient.amuletRulesInflight.get(key)\n if (!inflight) {\n inflight = this.fetchAmuletRulesOnce().finally(() => {\n ScanClient.amuletRulesInflight.delete(key)\n })\n ScanClient.amuletRulesInflight.set(key, inflight)\n }\n\n const contract = await inflight\n return structuredClone(contract)\n }\n\n public static invalidateAmuletRulesCache(baseUrl: URL) {\n const key = baseUrl.href\n this.amuletRulesCache.delete(key)\n this.amuletRulesInflight.delete(key)\n }\n\n private computeNextChangeAt(rounds: ScanTypes['Contract'][]): number {\n const now = Date.now()\n let next = Number.POSITIVE_INFINITY\n\n for (const round of rounds) {\n const { opensAt, targetClosesAt } = round.payload ?? {}\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n\n if (Number.isFinite(openMs) && openMs > now && openMs < next) {\n next = openMs\n }\n if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) {\n next = closeMs\n }\n }\n\n // If we couldn't parse anything sensible, force an immediate refresh.\n return Number.isFinite(next) ? next : now\n }\n\n private async fetchOpenMiningRoundsOnce(): Promise<\n ScanTypes['Contract'][]\n > {\n const resp = await this.post('/v0/open-and-issuing-mining-rounds', {\n cached_open_mining_round_contract_ids: [],\n cached_issuing_round_contract_ids: [],\n })\n\n const rounds = Object.values(resp.open_mining_rounds).flatMap((x) =>\n x.contract ? [x.contract] : []\n )\n\n const key = this.baseUrlHref\n ScanClient.roundsCache.set(key, rounds)\n ScanClient.roundsNextChangeAt.set(key, this.computeNextChangeAt(rounds))\n return rounds\n }\n\n private async refreshRounds(key: string): Promise<ScanTypes['Contract'][]> {\n let inflight = ScanClient.roundsInflight.get(key)\n if (!inflight) {\n inflight = this.fetchOpenMiningRoundsOnce().finally(() => {\n ScanClient.roundsInflight.delete(key)\n })\n ScanClient.roundsInflight.set(key, inflight)\n }\n return inflight\n }\n\n public async getOpenMiningRounds(): Promise<ScanTypes['Contract'][]> {\n const key = this.baseUrlHref\n const now = Date.now()\n const cached = ScanClient.roundsCache.get(key)\n const next = ScanClient.roundsNextChangeAt.get(key)\n\n if (cached && next !== undefined && now < next) {\n return structuredClone(cached)\n }\n const fresh = await this.refreshRounds(key)\n return structuredClone(fresh)\n }\n\n public async getActiveOpenMiningRound(): Promise<\n ScanTypes['Contract'] | null\n > {\n const pickActive = (\n rounds: ScanTypes['Contract'][],\n timestamp: number\n ) =>\n rounds\n .filter((round) => {\n const { opensAt, targetClosesAt } = round.payload\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n return (\n Number.isFinite(openMs) &&\n Number.isFinite(closeMs) &&\n openMs <= timestamp &&\n timestamp < closeMs\n )\n })\n .sort((a, b) => a.payload.opensAt - b.payload.opensAt)\n .at(-1) ?? null\n\n const now = Date.now()\n const rounds = await this.getOpenMiningRounds()\n const active = pickActive(rounds, now)\n return active ? structuredClone(active) : null\n }\n\n public static invalidateOpenMiningRoundsCache(baseUrl: URL) {\n const key = baseUrl.href\n this.roundsCache.delete(key)\n this.roundsInflight.delete(key)\n this.roundsNextChangeAt.delete(key)\n }\n\n public async isDevNet(): Promise<boolean> {\n const amuletRules = await this.getAmuletRules()\n const payload = amuletRules.payload as { isDevNet?: boolean }\n return payload?.isDevNet ?? false\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { components, paths } from './generated-clients/scan-proxy'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\nexport type ScanProxyTypes = components['schemas']\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ScanProxyClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private readonly accessTokenProvider: AccessTokenProvider\n private readonly baseUrlHref: string\n // shared caches for all instances of ScanProxyClient\n private static amuletRulesCache = new Map<\n string,\n ScanProxyTypes['Contract']\n >()\n private static roundsCache = new Map<string, ScanProxyTypes['Contract'][]>()\n // one in-flight fetch per baseUrl for rules/rounds\n private static amuletRulesInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract']>\n >()\n private static roundsInflight = new Map<\n string,\n Promise<ScanProxyTypes['Contract'][]>\n >()\n // time after surpassing which mining rounds should be refreshed\n private static roundsNextChangeAt = new Map<string, number>()\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.baseUrlHref = baseUrl.href\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ScanProxyClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n\n private async fetchAmuletRulesOnce(): Promise<ScanProxyTypes['Contract']> {\n const resp = await this.get('/v0/scan-proxy/amulet-rules')\n const contract = resp?.amulet_rules?.contract\n if (!contract?.contract_id || !contract?.template_id) {\n throw new Error('Malformed AmuletRules response')\n }\n ScanProxyClient.amuletRulesCache.set(this.baseUrlHref, contract)\n return contract\n }\n\n public async getAmuletRules(): Promise<ScanProxyTypes['Contract']> {\n const key = this.baseUrlHref\n\n const cached = ScanProxyClient.amuletRulesCache.get(key)\n // clone to prevent external mutation of cache by object reference\n if (cached) return structuredClone(cached)\n\n let inflight = ScanProxyClient.amuletRulesInflight.get(key)\n if (!inflight) {\n inflight = this.fetchAmuletRulesOnce().finally(() => {\n ScanProxyClient.amuletRulesInflight.delete(key)\n })\n ScanProxyClient.amuletRulesInflight.set(key, inflight)\n }\n\n const contract = await inflight\n return structuredClone(contract)\n }\n\n public static invalidateAmuletRulesCache(baseUrl: URL) {\n const key = baseUrl.href\n this.amuletRulesCache.delete(key)\n this.amuletRulesInflight.delete(key)\n }\n\n private computeNextChangeAt(rounds: ScanProxyTypes['Contract'][]): number {\n const now = Date.now()\n let next = Number.POSITIVE_INFINITY\n\n for (const round of rounds) {\n const { opensAt, targetClosesAt } = round.payload ?? {}\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n\n if (Number.isFinite(openMs) && openMs > now && openMs < next) {\n next = openMs\n }\n if (Number.isFinite(closeMs) && closeMs > now && closeMs < next) {\n next = closeMs\n }\n }\n\n // If we couldn't parse anything sensible, force an immediate refresh.\n return Number.isFinite(next) ? next : now\n }\n\n private async fetchOpenMiningRoundsOnce(): Promise<\n ScanProxyTypes['Contract'][]\n > {\n const resp = await this.get(\n '/v0/scan-proxy/open-and-issuing-mining-rounds'\n )\n const rounds = (resp.open_mining_rounds ?? []).map(\n (x) => x.contract\n ) as ScanProxyTypes['Contract'][]\n\n const key = this.baseUrlHref\n ScanProxyClient.roundsCache.set(key, rounds)\n ScanProxyClient.roundsNextChangeAt.set(\n key,\n this.computeNextChangeAt(rounds)\n )\n return rounds\n }\n\n private async refreshRounds(\n key: string\n ): Promise<ScanProxyTypes['Contract'][]> {\n let inflight = ScanProxyClient.roundsInflight.get(key)\n if (!inflight) {\n inflight = this.fetchOpenMiningRoundsOnce().finally(() => {\n ScanProxyClient.roundsInflight.delete(key)\n })\n ScanProxyClient.roundsInflight.set(key, inflight)\n }\n return inflight\n }\n\n public async getOpenMiningRounds(): Promise<ScanProxyTypes['Contract'][]> {\n const key = this.baseUrlHref\n const now = Date.now()\n const cached = ScanProxyClient.roundsCache.get(key)\n const next = ScanProxyClient.roundsNextChangeAt.get(key)\n\n if (cached && next !== undefined && now < next) {\n return structuredClone(cached)\n }\n const fresh = await this.refreshRounds(key)\n return structuredClone(fresh)\n }\n\n public async getActiveOpenMiningRound(): Promise<\n ScanProxyTypes['Contract'] | null\n > {\n const pickActive = (\n rounds: ScanProxyTypes['Contract'][],\n timestamp: number\n ) =>\n rounds\n .filter((round) => {\n const { opensAt, targetClosesAt } = round.payload\n const openMs = opensAt ? Number(new Date(opensAt)) : NaN\n const closeMs = targetClosesAt\n ? Number(new Date(targetClosesAt))\n : NaN\n return (\n Number.isFinite(openMs) &&\n Number.isFinite(closeMs) &&\n openMs <= timestamp &&\n timestamp < closeMs\n )\n })\n .sort((a, b) => a.payload.opensAt - b.payload.opensAt)\n .at(-1) ?? null\n\n const now = Date.now()\n const rounds = await this.getOpenMiningRounds()\n const active = pickActive(rounds, now)\n return active ? structuredClone(active) : null\n }\n\n public static invalidateOpenMiningRoundsCache(baseUrl: URL) {\n const key = baseUrl.href\n this.roundsCache.delete(key)\n this.roundsInflight.delete(key)\n this.roundsNextChangeAt.delete(key)\n }\n\n public async getAmuletSynchronizerId(): Promise<string | undefined> {\n type FutureValue = {\n decentralizedSynchronizer?: {\n activeSynchronizer?: string\n }\n }\n\n type Payload = {\n configSchedule?: {\n initialValue?: FutureValue\n futureValues?: FutureValue[]\n }\n }\n\n const amuletRules = await this.getAmuletRules()\n const payloadObj = amuletRules.payload as Payload\n\n const initActiveSynchronizer =\n payloadObj?.configSchedule?.initialValue?.decentralizedSynchronizer\n ?.activeSynchronizer\n const futureValues = payloadObj?.configSchedule?.futureValues\n\n if (Array.isArray(futureValues) && futureValues.length > 0) {\n let updatedValue: string | undefined = undefined\n for (const value of futureValues) {\n const parsed = JSON.parse(JSON.stringify(value))\n if (parsed?.decentralizedSynchronizer?.activeSynchronizer) {\n updatedValue =\n parsed.decentralizedSynchronizer.activeSynchronizer\n }\n }\n return updatedValue ?? initActiveSynchronizer\n } else return initActiveSynchronizer\n }\n\n public async isDevNet(): Promise<boolean> {\n const amuletRules = await this.getAmuletRules()\n const payload = amuletRules.payload as { isDevNet?: boolean }\n return payload?.isDevNet ?? false\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { paths } from './generated-clients/validator-internal'\nimport createClient, { Client } from 'openapi-fetch'\nimport { Logger } from '@canton-network/core-types'\nimport { AccessTokenProvider } from '@canton-network/core-wallet-auth'\n\n// A conditional type that filters the set of OpenAPI path names to those that actually have a defined POST operation.\n// Any path without a POST is excluded via the `never` branch of the conditional\ntype PostEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n post: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Given a pathname (string) that has a POST, this helper type extracts the request body type from the OpenAPI definition.\nexport type PostRequest<Path extends PostEndpoint> = paths[Path] extends {\n post: { requestBody: { content: { 'application/json': infer Req } } }\n}\n ? Req\n : never\n\n// Given a pathname (string) that has a POST, this helper type extracts the 200 response type from the OpenAPI definition.\nexport type PostResponse<Path extends PostEndpoint> = paths[Path] extends {\n post: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\n// Similar as above, for GETs\ntype GetEndpoint = {\n [Pathname in keyof paths]: paths[Pathname] extends {\n get: unknown\n }\n ? Pathname\n : never\n}[keyof paths]\n\n// Similar as above, for GETs\nexport type GetResponse<Path extends GetEndpoint> = paths[Path] extends {\n get: { responses: { 200: { content: { 'application/json': infer Res } } } }\n}\n ? Res\n : never\n\nexport class ValidatorInternalClient {\n private readonly client: Client<paths>\n private readonly logger: Logger\n private accessTokenProvider: AccessTokenProvider\n\n constructor(\n baseUrl: URL,\n logger: Logger,\n accessTokenProvider: AccessTokenProvider\n ) {\n this.accessTokenProvider = accessTokenProvider\n this.logger = logger\n this.logger.debug({ baseUrl }, 'ValidatorInternalClient initialized')\n this.client = createClient<paths>({\n baseUrl: baseUrl.href,\n fetch: async (url: RequestInfo, options: RequestInit = {}) => {\n const accessToken =\n await this.accessTokenProvider.getAccessToken()\n\n return fetch(url, {\n ...options,\n headers: {\n ...(options.headers || {}),\n ...(accessToken\n ? { Authorization: `Bearer ${accessToken}` }\n : {}),\n 'Content-Type': 'application/json',\n },\n })\n },\n })\n }\n\n public async post<Path extends PostEndpoint>(\n path: Path,\n body: PostRequest<Path>,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<PostResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { body, params } as any\n this.logger.debug({ requestBody: body }, `POST ${path}`)\n const resp = await this.client.POST(path, options)\n this.logger.debug({ requestBody: body, response: resp }, `POST ${path}`)\n return this.valueOrError(resp)\n }\n\n public async get<Path extends GetEndpoint>(\n path: Path,\n params?: {\n path?: Record<string, string>\n query?: Record<string, string>\n }\n ): Promise<GetResponse<Path>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- (cant align this with openapi-fetch generics :shrug:)\n const options = { params } as any\n\n const resp = await this.client.GET(path, options)\n this.logger.debug(\n { path: path, params: params, response: resp },\n `GET ${path}`\n )\n return this.valueOrError(resp)\n }\n\n private async valueOrError<T>(response: {\n data?: T\n error?: unknown\n }): Promise<T> {\n if (response.data === undefined) {\n return Promise.reject(response.error)\n } else {\n return Promise.resolve(response.data)\n }\n }\n}\n"]} |
@@ -51,2 +51,7 @@ import { components, paths } from './generated-clients/scan'; | ||
| private readonly baseUrlHref; | ||
| private static amuletRulesCache; | ||
| private static roundsCache; | ||
| private static amuletRulesInflight; | ||
| private static roundsInflight; | ||
| private static roundsNextChangeAt; | ||
| constructor(baseUrl: URL, logger: Logger, accessTokenProvider: AccessTokenProvider); | ||
@@ -63,4 +68,14 @@ post<Path extends PostEndpoint>(path: Path, body: PostRequest<Path>, params?: { | ||
| getAmuletSynchronizerId(): Promise<string | undefined>; | ||
| private fetchAmuletRulesOnce; | ||
| getAmuletRules(): Promise<ScanTypes['Contract']>; | ||
| static invalidateAmuletRulesCache(baseUrl: URL): void; | ||
| private computeNextChangeAt; | ||
| private fetchOpenMiningRoundsOnce; | ||
| private refreshRounds; | ||
| getOpenMiningRounds(): Promise<ScanTypes['Contract'][]>; | ||
| getActiveOpenMiningRound(): Promise<ScanTypes['Contract'] | null>; | ||
| static invalidateOpenMiningRoundsCache(baseUrl: URL): void; | ||
| isDevNet(): Promise<boolean>; | ||
| } | ||
| export {}; | ||
| //# sourceMappingURL=scan-client.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"scan-client.d.ts","sourceRoot":"","sources":["../src/scan-client.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,0BAA0B,CAAA;AAE5D,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAEtE,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;AAI7C,KAAK,YAAY,GAAG;KACf,QAAQ,IAAI,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS;QAC/C,IAAI,EAAE,OAAO,CAAA;KAChB,GACK,QAAQ,GACR,KAAK;CACd,CAAC,MAAM,KAAK,CAAC,CAAA;AAGd,MAAM,MAAM,WAAW,CAAC,IAAI,SAAS,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS;IACrE,IAAI,EAAE;QAAE,WAAW,EAAE;YAAE,OAAO,EAAE;gBAAE,kBAAkB,EAAE,MAAM,GAAG,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAA;CACxE,GACK,GAAG,GACH,KAAK,CAAA;AAGX,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,YAAY,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS;IACtE,IAAI,EAAE;QAAE,SAAS,EAAE;YAAE,GAAG,EAAE;gBAAE,OAAO,EAAE;oBAAE,kBAAkB,EAAE,MAAM,GAAG,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAA;CAC/E,GACK,GAAG,GACH,KAAK,CAAA;AAGX,KAAK,WAAW,GAAG;KACd,QAAQ,IAAI,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS;QAC/C,GAAG,EAAE,OAAO,CAAA;KACf,GACK,QAAQ,GACR,KAAK;CACd,CAAC,MAAM,KAAK,CAAC,CAAA;AAGd,MAAM,MAAM,WAAW,CAAC,IAAI,SAAS,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS;IACpE,GAAG,EAAE;QAAE,SAAS,EAAE;YAAE,GAAG,EAAE;gBAAE,OAAO,EAAE;oBAAE,kBAAkB,EAAE,MAAM,GAAG,CAAA;iBAAE,CAAA;aAAE,CAAA;SAAE,CAAA;KAAE,CAAA;CAC9E,GACK,GAAG,GACH,KAAK,CAAA;AAEX,qBAAa,UAAU;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;gBAGhC,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,mBAAmB;IA2B/B,IAAI,CAAC,IAAI,SAAS,YAAY,EACvC,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EACvB,MAAM,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACjC,GACF,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IASjB,GAAG,CAAC,IAAI,SAAS,WAAW,EACrC,IAAI,EAAE,IAAI,EACV,MAAM,CAAC,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAC7B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KACjC,GACF,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAYf,YAAY;IAWb,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CAwBtE"} | ||
| {"version":3,"file":"scan-client.d.ts","sourceRoot":"","sources":["../src/scan-client.ts"],"names":[],"mappings":"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"} |
+3
-3
| { | ||
| "name": "@canton-network/core-splice-client", | ||
| "version": "1.7.0", | ||
| "version": "1.8.0", | ||
| "type": "module", | ||
@@ -27,4 +27,4 @@ "description": "Typescript Client for the multiple Canton Network APIs", | ||
| "dependencies": { | ||
| "@canton-network/core-types": "^1.7.0", | ||
| "@canton-network/core-wallet-auth": "^1.7.0", | ||
| "@canton-network/core-types": "^1.8.0", | ||
| "@canton-network/core-wallet-auth": "^1.8.0", | ||
| "openapi-fetch": "^0.17.0", | ||
@@ -31,0 +31,0 @@ "uuid": "^14.0.0", |
557241
5.92%8562
2.8%