@relayerfi/widget-kit-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/client-key.ts","../src/utils/format.ts","../src/utils/constants.ts","../src/utils/proxify.ts","../src/errors/Errors.ts","../src/directory/WidgetDirectory.ts"],"sourcesContent":["export * from './utils';\nexport * from './directory/WidgetDirectory';\nexport * from './directory/Directory';\nexport * from './errors/index';\n\nexport const VERSION = '0.1.2';\n","let globalClientKey: string = '';\n\n// Storage persistent for extension\nconst EXTENSION_STORAGE_KEY = 'relayer_client_key';\n\n// Get the appropriate storage API (Chrome or Firefox)\nfunction getStorageAPI() {\n if (typeof chrome !== 'undefined' && chrome.storage) {\n return chrome.storage;\n }\n\n //@ts-ignore\n if (typeof browser !== 'undefined' && browser.storage) {\n // @ts-ignore\n return browser.storage;\n }\n return null;\n}\n\nexport async function setClientKey(key: string): Promise<void> {\n if (!key || key.trim() === '') {\n throw new Error('Client key is required and cannot be empty');\n }\n\n globalClientKey = key;\n // If we are in the extension, let's try to store the client key\n const storage = getStorageAPI();\n if (storage) {\n try {\n await storage.local.set({ [EXTENSION_STORAGE_KEY]: key });\n } catch (error) {\n throw new Error('Failed to store client key in storage', { cause: error });\n }\n }\n}\n\nexport async function getClientKey(): Promise<string> {\n // Check if we have the key in memory\n if (globalClientKey && globalClientKey.trim() !== '') {\n return globalClientKey;\n }\n\n // If we are in the extension, let's try to get the client key from storage\n const storage = getStorageAPI();\n if (storage) {\n try {\n const result = await storage.local.get(EXTENSION_STORAGE_KEY);\n const storedKey = result[EXTENSION_STORAGE_KEY];\n\n if (storedKey) {\n globalClientKey = storedKey;\n return globalClientKey;\n }\n } catch (error) {\n throw new Error('Failed to get client key from storage', { cause: error });\n }\n }\n\n throw new Error('Client key not found');\n}\n\nexport function clearClientKey(): string | null {\n globalClientKey = '';\n return globalClientKey;\n}\n","// @relayerfi/widget-kit-core/src/utils/format.ts\n\n/**\n * Elimina el prefijo '0x' de una dirección hexadecimal si existe\n */\nexport function removeHexPrefix(address: string): string {\n return address.startsWith('0x') ? address.slice(2) : address;\n}\n\n/**\n * Añade el prefijo '0x' a una dirección hexadecimal si no existe\n */\nexport function addHexPrefix(address: string): string {\n return address.startsWith('0x') ? address : `0x${address}`;\n}\n\n/**\n * Formatea un valor como un número legible con un número específico de decimales\n */\nexport function formatNumber(value: number | string, decimals: number = 2): string {\n const num = typeof value === 'string' ? parseFloat(value) : value;\n return num.toLocaleString(undefined, {\n minimumFractionDigits: decimals,\n maximumFractionDigits: decimals,\n });\n}\n\n/**\n * Trunca una cadena a una longitud específica y añade puntos suspensivos\n */\nexport function truncateString(str: string, length: number = 4): string {\n if (str.length <= length * 2 + 3) return str;\n return `${str.substring(0, length)}...${str.substring(str.length - length)}`;\n}\n\n/**\n * Trunca una dirección de wallet para mostrarla de forma legible\n */\nexport function truncateAddress(address: string): string {\n return truncateString(removeHexPrefix(address), 4);\n}\n","export const PROXY_URL = 'https://proxy.relayer.fi';\nexport const API_REPOSITORY_URL = 'https://api.relayer.fi/v1/directory/v1';\n\nexport {\n SDK_TO_PROXY_HEADERS,\n PROXY_TO_DEV_HEADERS,\n RELAYER_VALUES,\n VALID_OPERATIONS,\n type ValidOperation,\n} from '@relayerfi/action-kit';\n","import { getClientKey } from './client-key';\nimport { PROXY_URL, SDK_TO_PROXY_HEADERS, RELAYER_VALUES } from './constants';\nimport {\n createDynamicExecutor,\n DynamicActionExecutor,\n WidgetExecutor,\n type DynamicAction,\n type ExecutionResponse,\n type BlockchainContext,\n type ValidatedMetadata,\n type Metadata,\n} from '@relayerfi/action-kit';\n\nexport interface ProxifyResult {\n url: string;\n headers: Record<string, string>;\n}\n\n/**\n * Prepares the URL and headers to make a request through the Relayer proxy.\n * Sends the target URL as a query parameter and the client_key (if exists) in an HTTP header.\n *\n * @param targetUrl The original URL to access.\n * @param isExtension Indicates if the request originates from the browser extension.\n * @returns An object with the `url` of the proxy and the `headers` to use in the fetch.\n */\nexport async function proxify(url: string, isExtension: boolean = false): Promise<ProxifyResult> {\n const clientKey = await getClientKey();\n\n // This should never happen, but we'll add a check just in case\n if (!clientKey) {\n throw new Error('Client key not found', { cause: new Error('Client key not found') });\n }\n\n const proxyEndpoint = `${PROXY_URL}/proxy`;\n const queryParams = new URLSearchParams();\n queryParams.set('url', url);\n\n const proxifiedUrl = `${proxyEndpoint}?${queryParams.toString()}`;\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n [SDK_TO_PROXY_HEADERS.USER_AGENT]: RELAYER_VALUES.USER_AGENT,\n [SDK_TO_PROXY_HEADERS.CONTENT_TYPE]: RELAYER_VALUES.CONTENT_TYPE_JSON,\n [SDK_TO_PROXY_HEADERS.CLIENT_KEY]: clientKey,\n };\n\n return { url: proxifiedUrl, headers };\n}\n\nasync function getDynamicExecutor(key?: string): Promise<DynamicActionExecutor> {\n if (!key) {\n return await createDynamicExecutor();\n } else {\n return createDynamicExecutor(key);\n }\n}\n\nexport async function execute(\n action: DynamicAction,\n inputs: Record<string, any>,\n context: BlockchainContext & { baseUrl: string },\n options?: any,\n): Promise<ExecutionResponse> {\n const clientKey = await getClientKey();\n\n if (!clientKey) {\n const executor = await getDynamicExecutor();\n return await executor.execute(action, inputs, context, options);\n } else {\n const executor = await getDynamicExecutor(clientKey);\n return await executor.execute(action, inputs, context, options);\n }\n}\n\nexport async function getMetadata(url: string): Promise<Metadata | ValidatedMetadata | null> {\n const clientKey = await getClientKey();\n\n const executor = clientKey ? new WidgetExecutor(clientKey) : new WidgetExecutor();\n\n return await executor.getMetadata(url);\n}\n","/**\n * Base error class for all Relayer application errors\n */\nexport class RelayerError extends Error {\n public readonly code: string;\n public readonly httpStatus?: number;\n public readonly originalError?: Error;\n public readonly context?: Record<string, unknown>;\n\n constructor({\n message,\n code = 'UNKNOWN_ERROR',\n httpStatus,\n originalError,\n context,\n }: {\n message: string;\n code?: string;\n httpStatus?: number;\n originalError?: Error;\n context?: Record<string, unknown>;\n }) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.httpStatus = httpStatus;\n this.originalError = originalError;\n this.context = context;\n\n // Maintain proper stack trace for where our error was thrown\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Convert error to a plain object for logging or serialization\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n httpStatus: this.httpStatus,\n stack: this.stack,\n context: this.context,\n originalError: this.originalError\n ? {\n message: this.originalError.message,\n name: this.originalError.name,\n stack: this.originalError.stack,\n }\n : undefined,\n };\n }\n}\n\n/**\n * Error for network-related issues\n */\nexport class NetworkError extends RelayerError {\n constructor({\n message,\n code = 'NETWORK_ERROR',\n httpStatus,\n originalError,\n context,\n }: {\n message: string;\n code?: string;\n httpStatus?: number;\n originalError?: Error;\n context?: Record<string, unknown>;\n }) {\n super({ message, code, httpStatus, originalError, context });\n }\n\n static fromFetchError(url: string, error: Error, httpStatus?: number): NetworkError {\n return new NetworkError({\n message: `Network request failed for ${url}`,\n code: 'FETCH_ERROR',\n httpStatus,\n originalError: error,\n context: { url },\n });\n }\n}\n\n/**\n * Error for validation failures\n */\nexport class ValidationError extends RelayerError {\n public readonly invalidFields?: Record<string, string>;\n\n constructor({\n message,\n code = 'VALIDATION_ERROR',\n invalidFields,\n context,\n }: {\n message: string;\n code?: string;\n invalidFields?: Record<string, string>;\n context?: Record<string, unknown>;\n }) {\n super({ message, code, context });\n this.invalidFields = invalidFields;\n }\n\n static missingField(fieldName: string): ValidationError {\n return new ValidationError({\n message: `Missing required field: ${fieldName}`,\n code: 'MISSING_FIELD',\n invalidFields: { [fieldName]: 'Field is required' },\n });\n }\n\n static invalidFormat(fieldName: string, reason: string): ValidationError {\n return new ValidationError({\n message: `Invalid format for ${fieldName}: ${reason}`,\n code: 'INVALID_FORMAT',\n invalidFields: { [fieldName]: reason },\n });\n }\n}\n\n/**\n * Error for security-related issues\n */\nexport class SecurityError extends RelayerError {\n constructor({\n message,\n code = 'SECURITY_ERROR',\n context,\n }: {\n message: string;\n code?: string;\n context?: Record<string, unknown>;\n }) {\n super({ message, code, context });\n }\n}\n\n/**\n * Error for blockchain interaction issues\n */\nexport class BlockchainError extends RelayerError {\n constructor({\n message,\n code = 'BLOCKCHAIN_ERROR',\n originalError,\n context,\n }: {\n message: string;\n code?: string;\n originalError?: Error;\n context?: Record<string, unknown>;\n }) {\n super({ message, code, originalError, context });\n }\n\n static transactionFailed(reason: string, context?: Record<string, unknown>): BlockchainError {\n return new BlockchainError({\n message: `Transaction failed: ${reason}`,\n code: 'TRANSACTION_FAILED',\n context,\n });\n }\n\n static walletConnectionFailed(reason: string): BlockchainError {\n return new BlockchainError({\n message: `Failed to connect to wallet: ${reason}`,\n code: 'WALLET_CONNECTION_ERROR',\n });\n }\n}\n\n/**\n * Error for when resources are not found\n */\nexport class NotFoundError extends RelayerError {\n constructor({\n message,\n code = 'NOT_FOUND',\n httpStatus = 404,\n context,\n }: {\n message: string;\n code?: string;\n httpStatus?: number;\n context?: Record<string, unknown>;\n }) {\n super({ message, code, httpStatus, context });\n }\n\n static resourceNotFound(resourceType: string, identifier: string): NotFoundError {\n return new NotFoundError({\n message: `${resourceType} not found: ${identifier}`,\n context: { resourceType, identifier },\n });\n }\n}\n\n/**\n * Error for operations that can't be performed in the current state\n */\nexport class InvalidOperationError extends RelayerError {\n constructor({\n message,\n code = 'INVALID_OPERATION',\n context,\n }: {\n message: string;\n code?: string;\n context?: Record<string, unknown>;\n }) {\n super({ message, code, context });\n }\n\n static actionNotPermitted(action: string, reason: string): InvalidOperationError {\n return new InvalidOperationError({\n message: `Operation not permitted: ${action}. Reason: ${reason}`,\n context: { action, reason },\n });\n }\n}\n\n/**\n * Error for widget-specific issues\n */\nexport class WidgetError extends RelayerError {\n constructor({\n message,\n code = 'WIDGET_ERROR',\n httpStatus,\n originalError,\n context,\n }: {\n message: string;\n code?: string;\n httpStatus?: number;\n originalError?: Error;\n context?: Record<string, unknown>;\n }) {\n super({ message, code, httpStatus, originalError, context });\n }\n\n static metadataFetchFailed(url: string, httpStatus: number): WidgetError {\n return new WidgetError({\n message: `Failed to fetch widget metadata from ${url}`,\n code: 'METADATA_FETCH_FAILED',\n httpStatus,\n context: { url },\n });\n }\n\n static invalidUrl(url: string, reason: string): WidgetError {\n return new WidgetError({\n message: `Invalid widget URL: ${url}. Reason: ${reason}`,\n code: 'INVALID_URL',\n context: { url, reason },\n });\n }\n\n static invalidMetadata(reason: string, originalError?: Error): WidgetError {\n return new WidgetError({\n message: `Invalid widget metadata: ${reason}`,\n code: 'INVALID_METADATA',\n originalError,\n context: { reason },\n });\n }\n\n static actionError(actionIndex: number, reason: string): WidgetError {\n return new WidgetError({\n message: `Failed to execute widget action at index ${actionIndex}: ${reason}`,\n code: 'ACTION_EXECUTION_ERROR',\n context: { actionIndex, reason },\n });\n }\n\n /**\n * Error when fetching the widget directory fails.\n * @param url The URL that was fetched.\n * @param httpStatus The HTTP status code received.\n * @param statusText Optional status text from the response.\n */\n static directoryFetchFailed(\n url: string,\n httpStatus: number,\n statusText?: string,\n ): WidgetError {\n return new WidgetError({\n message: `Failed to fetch widget directory from ${url}. Status: ${httpStatus}${statusText ? ` (${statusText})` : ''}`,\n code: 'REGISTRY_FETCH_FAILED',\n httpStatus,\n context: { url },\n });\n }\n\n /**\n * Error when the fetched directory data has an invalid format.\n * @param reason Description of why the format is invalid.\n */\n static invalidDirectoryFormat(reason: string): WidgetError {\n return new WidgetError({\n message: `Invalid widget directory format: ${reason}`,\n code: 'INVALID_REGISTRY_FORMAT',\n context: { reason },\n });\n }\n\n /**\n * Generic error during the directory refresh process.\n * @param reason Description of the error.\n * @param originalError The original error caught, if any.\n */\n static directoryRefreshError(reason: string, originalError?: Error): WidgetError {\n return new WidgetError({\n message: `Error during widget directory refresh: ${reason}`,\n code: 'REGISTRY_REFRESH_ERROR',\n originalError,\n context: { reason },\n });\n }\n}\n\n/**\n * Helper functions for error handling\n */\nexport const ErrorUtils = {\n /**\n * Safely wrap async operations with consistent error handling\n */\n async safeAsync<T>(\n promise: Promise<T>,\n errorMapper?: (err: unknown) => RelayerError,\n ): Promise<T> {\n try {\n return await promise;\n } catch (error) {\n if (errorMapper) {\n throw errorMapper(error);\n }\n if (error instanceof RelayerError) {\n throw error;\n }\n throw new RelayerError({\n message: error instanceof Error ? error.message : String(error),\n originalError: error instanceof Error ? error : undefined,\n });\n }\n },\n};\n\n","import { WidgetError } from '../errors/Errors';\nimport { API_REPOSITORY_URL } from '../utils/constants';\nimport type { WidgetSecurityState } from './Directory';\nimport type { WidgetEntry } from './Directory';\n\nexport interface WidgetDirectoryConfig {\n mini_apps: WidgetEntry[];\n lastUpdated: string;\n}\n\nexport interface DirectoryInitializationConfig {\n refreshInterval?: number;\n cacheInStorage?: boolean;\n forceRefresh?: boolean; // Opción para forzar la recarga\n}\n\nexport class WidgetDirectory {\n private static instance: WidgetDirectory | null = null;\n private widgetsByHostAndPath: Map<string, WidgetEntry> = new Map();\n private widgetsByHost: Map<string, WidgetEntry[]> = new Map();\n private lastUpdated: Date = new Date(0);\n private isRefreshing: boolean = false;\n private isExtension: boolean = false;\n private defaultDirectoryUrl: string;\n\n private initializationPromise: Promise<void> | null = null;\n private isInitialized: boolean = false;\n private refreshIntervalId: any = null; // Para almacenar el ID del intervalo\n\n private constructor(config: DirectoryInitializationConfig = {}) {\n this.isExtension = typeof chrome !== 'undefined' && chrome.runtime && !!chrome.runtime.id;\n //console.log(\n // `[widget-kit] Running in ${this.isExtension ? 'extension' : 'website'} mode`,\n //);\n this.defaultDirectoryUrl = API_REPOSITORY_URL;\n }\n\n public static getInstance(config: DirectoryInitializationConfig = {}): WidgetDirectory {\n if (!this.instance) {\n this.instance = new WidgetDirectory(config);\n }\n return this.instance;\n }\n\n public async init(config: DirectoryInitializationConfig = {}): Promise<void> {\n if (this.isInitialized && !config.forceRefresh) {\n //console.log('[widget-kit] Directory already initialized.');\n return;\n }\n\n if (this.initializationPromise && !config.forceRefresh) {\n //console.log(\n // '[widget-kit] Initialization already in progress, awaiting existing promise.',\n //);\n return this.initializationPromise;\n }\n\n // Si se fuerza el refresco, reseteamos el estado de inicialización\n if (config.forceRefresh) {\n //console.log('[widget-kit] Force refresh requested.');\n this.isInitialized = false;\n }\n\n this.initializationPromise = (async () => {\n try {\n //console.log('[widget-kit] Starting directory initialization/refresh.');\n const urlToRefresh = this.defaultDirectoryUrl;\n // refresh() ya tiene su propio guard 'isRefreshing'\n await this.refresh(urlToRefresh);\n\n if (this.isExtension && config?.refreshInterval) {\n if (this.refreshIntervalId) {\n clearInterval(this.refreshIntervalId);\n }\n this.refreshIntervalId = setInterval(() => {\n this.refresh(urlToRefresh).catch(error => {\n //console.error(\n // '[widget-kit] Error during periodic directory refresh:',\n // error,\n //);\n });\n }, config.refreshInterval);\n //console.log(\n // `[widget-kit] Periodic refresh set up every ${config.refreshInterval}ms.`,\n //);\n }\n this.isInitialized = true;\n //console.log(\n // '[widget-kit] Directory initialization/refresh completed successfully.',\n //);\n } catch (error) {\n //console.error('[widget-kit] Directory initialization/refresh failed:', error);\n this.isInitialized = false; // Asegurar que esté en false si falla\n throw error; // Re-lanzar para que los llamadores lo manejen\n } finally {\n // Limpiar la promesa para permitir reintentos si falló, o si se usa forceRefresh\n this.initializationPromise = null;\n }\n })();\n return this.initializationPromise;\n }\n\n private createKey(host: string, pathname: string): string {\n return `${host}${pathname}`;\n }\n\n private normalizeHost(hostInput: string): string {\n let host = hostInput;\n if (host.startsWith('http://') || host.startsWith('https://')) {\n try {\n // Usar hostInput que es el parámetro original\n const url = new URL(hostInput);\n host = url.host;\n } catch (e) {\n //console.warn(`[widget-kit] Could not parse host: ${hostInput}, using as-is`);\n // Si falla el parseo de URL (ej. no es una URL completa), intentar extraer el host de otra forma o usar como está\n // Esto puede pasar si hostInput es algo como \"api.example.com/v1\" y se pasa a new URL()\n // Una heurística simple si no es una URL válida:\n const match = hostInput.match(/^https?:\\/\\/([^/?#]+)/i);\n if (match && match[1]) {\n host = match[1];\n } else {\n // Si no, asumir que es un hostname o un string que no podemos normalizar más aquí\n host = hostInput.split('/')[0] || hostInput; // Tomar la primera parte antes de un /\n }\n }\n }\n\n if (host.startsWith('www.')) {\n host = host.substring(4);\n }\n return host;\n }\n\n public lookup(url: string | URL): { state: WidgetSecurityState; id?: string } {\n if (!this.isInitialized) {\n //console.warn(\n // '[widget-kit] Lookup called before directory is initialized. Returning \"unknown\". This might indicate an issue with awaiting directory.init().',\n //);\n return { state: 'unknown' };\n }\n //console.log(`[widget-kit] Looking up URL: ${url}`);\n try {\n const urlObj = typeof url === 'string' ? new URL(url) : url;\n const host = this.normalizeHost(urlObj.host);\n const pathname = urlObj.pathname;\n\n //console.log(`[widget-kit] Parsed - Host: ${host}, Path: ${pathname}`);\n\n const exactKey = this.createKey(host, pathname);\n const exactMatch = this.widgetsByHostAndPath.get(exactKey);\n\n if (exactMatch) {\n //console.log(\n // `[widget-kit] Exact match found for ${exactKey}: ${exactMatch.state}`,\n //);\n return { state: exactMatch.state, id: exactMatch.id };\n }\n\n const hostApps = this.widgetsByHost.get(host);\n if (hostApps && hostApps.length > 0) {\n //console.log(`[widget-kit] Found ${hostApps.length} apps for host ${host}`);\n for (const app of hostApps) {\n const appPath = app.path || '/'; // app.path ya debería estar normalizado en refresh\n if (pathname.startsWith(appPath)) {\n //console.log(\n // `[widget-kit] Path match found: ${appPath} matches ${pathname}, state: ${app.state}`,\n //);\n return { state: app.state, id: app.id };\n }\n }\n\n const maliciousApp = hostApps.find(app => app.state === 'malicious');\n if (maliciousApp) {\n //console.warn(\n // `[widget-kit] No specific path match for ${pathname} on host ${host}, but a malicious app exists for this host. Marking as malicious for safety.`,\n //);\n return { state: 'malicious', id: maliciousApp.id };\n }\n\n //console.log(\n // `[widget-kit] No specific path match for ${pathname} on host ${host}. Defaulting to unknown as no generic rule applies.`,\n //);\n\n // No se debe retornar hostApps[0].state si no hay un match de path, es más seguro retornar 'unknown'\n // a menos que haya una regla explícita para el host general (ej. path \"/\")\n const rootPathApp = hostApps.find(app => (app.path || '/') === '/');\n if (rootPathApp) {\n //console.log(\n // `[widget-kit] Using root path app state for host ${host}: ${rootPathApp.state}`,\n //);\n return { state: rootPathApp.state, id: rootPathApp.id };\n }\n\n return { state: 'unknown' };\n }\n\n //console.log(\n // `[widget-kit] No apps found for host ${host}. Returning unknown for ${host}${pathname}`,\n //);\n return { state: 'unknown' };\n } catch (error) {\n //console.error(`[widget-kit] Error looking up URL: ${url}`, error);\n return { state: 'unknown' };\n }\n }\n\n public async refresh(directoryUrl?: string): Promise<void> {\n if (this.isRefreshing) {\n //console.warn(`[widget-kit] Directory is already refreshing. Skipping...`);\n return;\n }\n\n const urlToFetch = directoryUrl || this.defaultDirectoryUrl;\n this.isRefreshing = true;\n //console.log(`[widget-kit] Refreshing directory from ${urlToFetch}`);\n\n try {\n const response = await fetch(urlToFetch, {\n headers: { 'Cache-Control': 'no-cache, no-store', Pragma: 'no-cache' },\n });\n\n if (!response.ok) {\n throw WidgetError.directoryFetchFailed(\n urlToFetch,\n response.status,\n response.statusText,\n );\n }\n\n const data = (await response.json()) as WidgetDirectoryConfig;\n\n if (!data || typeof data !== 'object' || !Array.isArray(data.mini_apps)) {\n throw WidgetError.invalidDirectoryFormat('Missing expected fields (mini_apps)');\n }\n\n const newWidgetsByHostAndPath: Map<string, WidgetEntry> = new Map();\n const newWidgetsByHost: Map<string, WidgetEntry[]> = new Map();\n\n for (const app of data.mini_apps as WidgetEntry[]) {\n if (app && typeof app === 'object' && app.host && app.state) {\n const originalAppHost = app.host; // Guardar para logging\n const normalizedHost = this.normalizeHost(app.host);\n const path = app.path || '/'; // Asegurar que path siempre tenga un valor\n\n // Crear una nueva instancia de app con el host y path normalizados\n const normalizedApp: WidgetEntry = { ...app, host: normalizedHost, path: path };\n\n const key = this.createKey(normalizedHost, path);\n newWidgetsByHostAndPath.set(key, normalizedApp);\n\n if (!newWidgetsByHost.has(normalizedHost)) {\n newWidgetsByHost.set(normalizedHost, []);\n }\n newWidgetsByHost.get(normalizedHost)!.push(normalizedApp);\n\n //console.log(\n // `[widget-kit] Loaded app (Original Host: ${originalAppHost}): ${normalizedHost}${path} -> ${app.state}`,\n //);\n } else {\n console.warn(\n '[widget-kit] Skipping invalid WidgetEntry during refresh:',\n app,\n );\n }\n }\n\n for (const [host, apps] of newWidgetsByHost) {\n apps.sort((a, b) => b.path!.length - a.path!.length); // path! porque ya lo normalizamos\n newWidgetsByHost.set(host, apps);\n }\n\n this.widgetsByHostAndPath = newWidgetsByHostAndPath;\n this.widgetsByHost = newWidgetsByHost;\n this.lastUpdated = new Date(data.lastUpdated);\n\n //console.log(\n // `[widget-kit] Directory refreshed successfully. ${this.widgetsByHostAndPath.size} widgets loaded. Last updated: ${this.lastUpdated.toISOString()}`,\n //);\n } catch (error) {\n //console.error(\n // `[widget-kit] Failed to refresh widget directory from ${urlToFetch}:`,\n // error,\n //);\n if (error instanceof WidgetError) throw error;\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw WidgetError.directoryRefreshError(\n errorMessage,\n error instanceof Error ? error : undefined,\n );\n } finally {\n this.isRefreshing = false;\n }\n }\n\n public getLastUpdated(): Date {\n return this.lastUpdated;\n }\n public getCurrentDirectory(): ReadonlyMap<string, WidgetEntry> {\n return this.widgetsByHostAndPath;\n }\n\n public debug(): void {\n console.log('=== Directory Debug ===');\n console.log(`Is Initialized: ${this.isInitialized}`);\n console.log(`Last Updated: ${this.lastUpdated.toISOString()}`);\n console.log('By Host + Path:');\n for (const [key, app] of this.widgetsByHostAndPath) {\n console.log(` ${key} -> State: ${app.state}, Path in App: ${app.path}`);\n }\n console.log('By Host (Sorted by path specificity):');\n for (const [host, apps] of this.widgetsByHost) {\n console.log(` ${host}:`);\n apps.forEach(app => console.log(` Path: ${app.path} -> State: ${app.state}`));\n }\n console.log('=======================');\n }\n}\n\n"],"mappings":"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","names":["import_action_kit"]}
@@ -0,0 +1,270 @@
1
+ import { DynamicAction, BlockchainContext, ExecutionResponse, Metadata, ValidatedMetadata } from '@relayerfi/action-kit';
2
+ export { PROXY_TO_DEV_HEADERS, RELAYER_VALUES, SDK_TO_PROXY_HEADERS, VALID_OPERATIONS, ValidOperation } from '@relayerfi/action-kit';
3
+
4
+ declare function setClientKey(key: string): Promise<void>;
5
+ declare function getClientKey(): Promise<string>;
6
+ declare function clearClientKey(): string | null;
7
+
8
+ /**
9
+ * Elimina el prefijo '0x' de una dirección hexadecimal si existe
10
+ */
11
+ declare function removeHexPrefix(address: string): string;
12
+ /**
13
+ * Añade el prefijo '0x' a una dirección hexadecimal si no existe
14
+ */
15
+ declare function addHexPrefix(address: string): string;
16
+ /**
17
+ * Formatea un valor como un número legible con un número específico de decimales
18
+ */
19
+ declare function formatNumber(value: number | string, decimals?: number): string;
20
+ /**
21
+ * Trunca una cadena a una longitud específica y añade puntos suspensivos
22
+ */
23
+ declare function truncateString(str: string, length?: number): string;
24
+ /**
25
+ * Trunca una dirección de wallet para mostrarla de forma legible
26
+ */
27
+ declare function truncateAddress(address: string): string;
28
+
29
+ interface ProxifyResult {
30
+ url: string;
31
+ headers: Record<string, string>;
32
+ }
33
+ /**
34
+ * Prepares the URL and headers to make a request through the Relayer proxy.
35
+ * Sends the target URL as a query parameter and the client_key (if exists) in an HTTP header.
36
+ *
37
+ * @param targetUrl The original URL to access.
38
+ * @param isExtension Indicates if the request originates from the browser extension.
39
+ * @returns An object with the `url` of the proxy and the `headers` to use in the fetch.
40
+ */
41
+ declare function proxify(url: string, isExtension?: boolean): Promise<ProxifyResult>;
42
+ declare function execute(action: DynamicAction, inputs: Record<string, any>, context: BlockchainContext & {
43
+ baseUrl: string;
44
+ }, options?: any): Promise<ExecutionResponse>;
45
+ declare function getMetadata(url: string): Promise<Metadata | ValidatedMetadata | null>;
46
+
47
+ declare const PROXY_URL = "https://proxy.relayer.fi";
48
+ declare const API_REPOSITORY_URL = "https://api.relayer.fi/v1/directory/v1";
49
+
50
+ type WidgetSecurityState = 'trusted' | 'malicious' | 'unknown';
51
+ interface IntegratorDomain {
52
+ domain: string;
53
+ state: WidgetSecurityState;
54
+ verifiedAt: string;
55
+ }
56
+ interface WidgetEntry {
57
+ id: string;
58
+ host: string;
59
+ state: WidgetSecurityState;
60
+ category: string;
61
+ subcategory?: string;
62
+ verifiedAt: string;
63
+ protocol?: string;
64
+ path: string;
65
+ }
66
+ interface Template {
67
+ id: string;
68
+ name: string;
69
+ protocol?: string;
70
+ path: string;
71
+ }
72
+ interface TemplateCategory {
73
+ id: string;
74
+ name: string;
75
+ templates: Template[];
76
+ }
77
+ interface TemplateDirectory {
78
+ baseUrl: string;
79
+ categories: TemplateCategory[];
80
+ }
81
+ interface MaliciousDomain {
82
+ domain: string;
83
+ reportedAt: string;
84
+ reportReason: string;
85
+ similarTo?: string;
86
+ }
87
+ interface DirectoryData {
88
+ lastUpdated: string;
89
+ version: string;
90
+ integrators: IntegratorDomain[];
91
+ mini_apps: WidgetEntry[];
92
+ templates: TemplateDirectory[];
93
+ maliciousDomains: MaliciousDomain[];
94
+ }
95
+
96
+ interface WidgetDirectoryConfig {
97
+ mini_apps: WidgetEntry[];
98
+ lastUpdated: string;
99
+ }
100
+ interface DirectoryInitializationConfig {
101
+ refreshInterval?: number;
102
+ cacheInStorage?: boolean;
103
+ forceRefresh?: boolean;
104
+ }
105
+ declare class WidgetDirectory {
106
+ private static instance;
107
+ private widgetsByHostAndPath;
108
+ private widgetsByHost;
109
+ private lastUpdated;
110
+ private isRefreshing;
111
+ private isExtension;
112
+ private defaultDirectoryUrl;
113
+ private initializationPromise;
114
+ private isInitialized;
115
+ private refreshIntervalId;
116
+ private constructor();
117
+ static getInstance(config?: DirectoryInitializationConfig): WidgetDirectory;
118
+ init(config?: DirectoryInitializationConfig): Promise<void>;
119
+ private createKey;
120
+ private normalizeHost;
121
+ lookup(url: string | URL): {
122
+ state: WidgetSecurityState;
123
+ id?: string;
124
+ };
125
+ refresh(directoryUrl?: string): Promise<void>;
126
+ getLastUpdated(): Date;
127
+ getCurrentDirectory(): ReadonlyMap<string, WidgetEntry>;
128
+ debug(): void;
129
+ }
130
+
131
+ /**
132
+ * Base error class for all Relayer application errors
133
+ */
134
+ declare class RelayerError extends Error {
135
+ readonly code: string;
136
+ readonly httpStatus?: number;
137
+ readonly originalError?: Error;
138
+ readonly context?: Record<string, unknown>;
139
+ constructor({ message, code, httpStatus, originalError, context, }: {
140
+ message: string;
141
+ code?: string;
142
+ httpStatus?: number;
143
+ originalError?: Error;
144
+ context?: Record<string, unknown>;
145
+ });
146
+ /**
147
+ * Convert error to a plain object for logging or serialization
148
+ */
149
+ toJSON(): Record<string, unknown>;
150
+ }
151
+ /**
152
+ * Error for network-related issues
153
+ */
154
+ declare class NetworkError extends RelayerError {
155
+ constructor({ message, code, httpStatus, originalError, context, }: {
156
+ message: string;
157
+ code?: string;
158
+ httpStatus?: number;
159
+ originalError?: Error;
160
+ context?: Record<string, unknown>;
161
+ });
162
+ static fromFetchError(url: string, error: Error, httpStatus?: number): NetworkError;
163
+ }
164
+ /**
165
+ * Error for validation failures
166
+ */
167
+ declare class ValidationError extends RelayerError {
168
+ readonly invalidFields?: Record<string, string>;
169
+ constructor({ message, code, invalidFields, context, }: {
170
+ message: string;
171
+ code?: string;
172
+ invalidFields?: Record<string, string>;
173
+ context?: Record<string, unknown>;
174
+ });
175
+ static missingField(fieldName: string): ValidationError;
176
+ static invalidFormat(fieldName: string, reason: string): ValidationError;
177
+ }
178
+ /**
179
+ * Error for security-related issues
180
+ */
181
+ declare class SecurityError extends RelayerError {
182
+ constructor({ message, code, context, }: {
183
+ message: string;
184
+ code?: string;
185
+ context?: Record<string, unknown>;
186
+ });
187
+ }
188
+ /**
189
+ * Error for blockchain interaction issues
190
+ */
191
+ declare class BlockchainError extends RelayerError {
192
+ constructor({ message, code, originalError, context, }: {
193
+ message: string;
194
+ code?: string;
195
+ originalError?: Error;
196
+ context?: Record<string, unknown>;
197
+ });
198
+ static transactionFailed(reason: string, context?: Record<string, unknown>): BlockchainError;
199
+ static walletConnectionFailed(reason: string): BlockchainError;
200
+ }
201
+ /**
202
+ * Error for when resources are not found
203
+ */
204
+ declare class NotFoundError extends RelayerError {
205
+ constructor({ message, code, httpStatus, context, }: {
206
+ message: string;
207
+ code?: string;
208
+ httpStatus?: number;
209
+ context?: Record<string, unknown>;
210
+ });
211
+ static resourceNotFound(resourceType: string, identifier: string): NotFoundError;
212
+ }
213
+ /**
214
+ * Error for operations that can't be performed in the current state
215
+ */
216
+ declare class InvalidOperationError extends RelayerError {
217
+ constructor({ message, code, context, }: {
218
+ message: string;
219
+ code?: string;
220
+ context?: Record<string, unknown>;
221
+ });
222
+ static actionNotPermitted(action: string, reason: string): InvalidOperationError;
223
+ }
224
+ /**
225
+ * Error for widget-specific issues
226
+ */
227
+ declare class WidgetError extends RelayerError {
228
+ constructor({ message, code, httpStatus, originalError, context, }: {
229
+ message: string;
230
+ code?: string;
231
+ httpStatus?: number;
232
+ originalError?: Error;
233
+ context?: Record<string, unknown>;
234
+ });
235
+ static metadataFetchFailed(url: string, httpStatus: number): WidgetError;
236
+ static invalidUrl(url: string, reason: string): WidgetError;
237
+ static invalidMetadata(reason: string, originalError?: Error): WidgetError;
238
+ static actionError(actionIndex: number, reason: string): WidgetError;
239
+ /**
240
+ * Error when fetching the widget directory fails.
241
+ * @param url The URL that was fetched.
242
+ * @param httpStatus The HTTP status code received.
243
+ * @param statusText Optional status text from the response.
244
+ */
245
+ static directoryFetchFailed(url: string, httpStatus: number, statusText?: string): WidgetError;
246
+ /**
247
+ * Error when the fetched directory data has an invalid format.
248
+ * @param reason Description of why the format is invalid.
249
+ */
250
+ static invalidDirectoryFormat(reason: string): WidgetError;
251
+ /**
252
+ * Generic error during the directory refresh process.
253
+ * @param reason Description of the error.
254
+ * @param originalError The original error caught, if any.
255
+ */
256
+ static directoryRefreshError(reason: string, originalError?: Error): WidgetError;
257
+ }
258
+ /**
259
+ * Helper functions for error handling
260
+ */
261
+ declare const ErrorUtils: {
262
+ /**
263
+ * Safely wrap async operations with consistent error handling
264
+ */
265
+ safeAsync<T>(promise: Promise<T>, errorMapper?: (err: unknown) => RelayerError): Promise<T>;
266
+ };
267
+
268
+ declare const VERSION = "0.1.2";
269
+
270
+ export { API_REPOSITORY_URL, BlockchainError, type DirectoryData, type DirectoryInitializationConfig, ErrorUtils, type IntegratorDomain, InvalidOperationError, type MaliciousDomain, NetworkError, NotFoundError, PROXY_URL, type ProxifyResult, RelayerError, SecurityError, type Template, type TemplateCategory, type TemplateDirectory, VERSION, ValidationError, WidgetDirectory, type WidgetDirectoryConfig, type WidgetEntry, WidgetError, type WidgetSecurityState, addHexPrefix, clearClientKey, execute, formatNumber, getClientKey, getMetadata, proxify, removeHexPrefix, setClientKey, truncateAddress, truncateString };
@@ -0,0 +1,270 @@
1
+ import { DynamicAction, BlockchainContext, ExecutionResponse, Metadata, ValidatedMetadata } from '@relayerfi/action-kit';
2
+ export { PROXY_TO_DEV_HEADERS, RELAYER_VALUES, SDK_TO_PROXY_HEADERS, VALID_OPERATIONS, ValidOperation } from '@relayerfi/action-kit';
3
+
4
+ declare function setClientKey(key: string): Promise<void>;
5
+ declare function getClientKey(): Promise<string>;
6
+ declare function clearClientKey(): string | null;
7
+
8
+ /**
9
+ * Elimina el prefijo '0x' de una dirección hexadecimal si existe
10
+ */
11
+ declare function removeHexPrefix(address: string): string;
12
+ /**
13
+ * Añade el prefijo '0x' a una dirección hexadecimal si no existe
14
+ */
15
+ declare function addHexPrefix(address: string): string;
16
+ /**
17
+ * Formatea un valor como un número legible con un número específico de decimales
18
+ */
19
+ declare function formatNumber(value: number | string, decimals?: number): string;
20
+ /**
21
+ * Trunca una cadena a una longitud específica y añade puntos suspensivos
22
+ */
23
+ declare function truncateString(str: string, length?: number): string;
24
+ /**
25
+ * Trunca una dirección de wallet para mostrarla de forma legible
26
+ */
27
+ declare function truncateAddress(address: string): string;
28
+
29
+ interface ProxifyResult {
30
+ url: string;
31
+ headers: Record<string, string>;
32
+ }
33
+ /**
34
+ * Prepares the URL and headers to make a request through the Relayer proxy.
35
+ * Sends the target URL as a query parameter and the client_key (if exists) in an HTTP header.
36
+ *
37
+ * @param targetUrl The original URL to access.
38
+ * @param isExtension Indicates if the request originates from the browser extension.
39
+ * @returns An object with the `url` of the proxy and the `headers` to use in the fetch.
40
+ */
41
+ declare function proxify(url: string, isExtension?: boolean): Promise<ProxifyResult>;
42
+ declare function execute(action: DynamicAction, inputs: Record<string, any>, context: BlockchainContext & {
43
+ baseUrl: string;
44
+ }, options?: any): Promise<ExecutionResponse>;
45
+ declare function getMetadata(url: string): Promise<Metadata | ValidatedMetadata | null>;
46
+
47
+ declare const PROXY_URL = "https://proxy.relayer.fi";
48
+ declare const API_REPOSITORY_URL = "https://api.relayer.fi/v1/directory/v1";
49
+
50
+ type WidgetSecurityState = 'trusted' | 'malicious' | 'unknown';
51
+ interface IntegratorDomain {
52
+ domain: string;
53
+ state: WidgetSecurityState;
54
+ verifiedAt: string;
55
+ }
56
+ interface WidgetEntry {
57
+ id: string;
58
+ host: string;
59
+ state: WidgetSecurityState;
60
+ category: string;
61
+ subcategory?: string;
62
+ verifiedAt: string;
63
+ protocol?: string;
64
+ path: string;
65
+ }
66
+ interface Template {
67
+ id: string;
68
+ name: string;
69
+ protocol?: string;
70
+ path: string;
71
+ }
72
+ interface TemplateCategory {
73
+ id: string;
74
+ name: string;
75
+ templates: Template[];
76
+ }
77
+ interface TemplateDirectory {
78
+ baseUrl: string;
79
+ categories: TemplateCategory[];
80
+ }
81
+ interface MaliciousDomain {
82
+ domain: string;
83
+ reportedAt: string;
84
+ reportReason: string;
85
+ similarTo?: string;
86
+ }
87
+ interface DirectoryData {
88
+ lastUpdated: string;
89
+ version: string;
90
+ integrators: IntegratorDomain[];
91
+ mini_apps: WidgetEntry[];
92
+ templates: TemplateDirectory[];
93
+ maliciousDomains: MaliciousDomain[];
94
+ }
95
+
96
+ interface WidgetDirectoryConfig {
97
+ mini_apps: WidgetEntry[];
98
+ lastUpdated: string;
99
+ }
100
+ interface DirectoryInitializationConfig {
101
+ refreshInterval?: number;
102
+ cacheInStorage?: boolean;
103
+ forceRefresh?: boolean;
104
+ }
105
+ declare class WidgetDirectory {
106
+ private static instance;
107
+ private widgetsByHostAndPath;
108
+ private widgetsByHost;
109
+ private lastUpdated;
110
+ private isRefreshing;
111
+ private isExtension;
112
+ private defaultDirectoryUrl;
113
+ private initializationPromise;
114
+ private isInitialized;
115
+ private refreshIntervalId;
116
+ private constructor();
117
+ static getInstance(config?: DirectoryInitializationConfig): WidgetDirectory;
118
+ init(config?: DirectoryInitializationConfig): Promise<void>;
119
+ private createKey;
120
+ private normalizeHost;
121
+ lookup(url: string | URL): {
122
+ state: WidgetSecurityState;
123
+ id?: string;
124
+ };
125
+ refresh(directoryUrl?: string): Promise<void>;
126
+ getLastUpdated(): Date;
127
+ getCurrentDirectory(): ReadonlyMap<string, WidgetEntry>;
128
+ debug(): void;
129
+ }
130
+
131
+ /**
132
+ * Base error class for all Relayer application errors
133
+ */
134
+ declare class RelayerError extends Error {
135
+ readonly code: string;
136
+ readonly httpStatus?: number;
137
+ readonly originalError?: Error;
138
+ readonly context?: Record<string, unknown>;
139
+ constructor({ message, code, httpStatus, originalError, context, }: {
140
+ message: string;
141
+ code?: string;
142
+ httpStatus?: number;
143
+ originalError?: Error;
144
+ context?: Record<string, unknown>;
145
+ });
146
+ /**
147
+ * Convert error to a plain object for logging or serialization
148
+ */
149
+ toJSON(): Record<string, unknown>;
150
+ }
151
+ /**
152
+ * Error for network-related issues
153
+ */
154
+ declare class NetworkError extends RelayerError {
155
+ constructor({ message, code, httpStatus, originalError, context, }: {
156
+ message: string;
157
+ code?: string;
158
+ httpStatus?: number;
159
+ originalError?: Error;
160
+ context?: Record<string, unknown>;
161
+ });
162
+ static fromFetchError(url: string, error: Error, httpStatus?: number): NetworkError;
163
+ }
164
+ /**
165
+ * Error for validation failures
166
+ */
167
+ declare class ValidationError extends RelayerError {
168
+ readonly invalidFields?: Record<string, string>;
169
+ constructor({ message, code, invalidFields, context, }: {
170
+ message: string;
171
+ code?: string;
172
+ invalidFields?: Record<string, string>;
173
+ context?: Record<string, unknown>;
174
+ });
175
+ static missingField(fieldName: string): ValidationError;
176
+ static invalidFormat(fieldName: string, reason: string): ValidationError;
177
+ }
178
+ /**
179
+ * Error for security-related issues
180
+ */
181
+ declare class SecurityError extends RelayerError {
182
+ constructor({ message, code, context, }: {
183
+ message: string;
184
+ code?: string;
185
+ context?: Record<string, unknown>;
186
+ });
187
+ }
188
+ /**
189
+ * Error for blockchain interaction issues
190
+ */
191
+ declare class BlockchainError extends RelayerError {
192
+ constructor({ message, code, originalError, context, }: {
193
+ message: string;
194
+ code?: string;
195
+ originalError?: Error;
196
+ context?: Record<string, unknown>;
197
+ });
198
+ static transactionFailed(reason: string, context?: Record<string, unknown>): BlockchainError;
199
+ static walletConnectionFailed(reason: string): BlockchainError;
200
+ }
201
+ /**
202
+ * Error for when resources are not found
203
+ */
204
+ declare class NotFoundError extends RelayerError {
205
+ constructor({ message, code, httpStatus, context, }: {
206
+ message: string;
207
+ code?: string;
208
+ httpStatus?: number;
209
+ context?: Record<string, unknown>;
210
+ });
211
+ static resourceNotFound(resourceType: string, identifier: string): NotFoundError;
212
+ }
213
+ /**
214
+ * Error for operations that can't be performed in the current state
215
+ */
216
+ declare class InvalidOperationError extends RelayerError {
217
+ constructor({ message, code, context, }: {
218
+ message: string;
219
+ code?: string;
220
+ context?: Record<string, unknown>;
221
+ });
222
+ static actionNotPermitted(action: string, reason: string): InvalidOperationError;
223
+ }
224
+ /**
225
+ * Error for widget-specific issues
226
+ */
227
+ declare class WidgetError extends RelayerError {
228
+ constructor({ message, code, httpStatus, originalError, context, }: {
229
+ message: string;
230
+ code?: string;
231
+ httpStatus?: number;
232
+ originalError?: Error;
233
+ context?: Record<string, unknown>;
234
+ });
235
+ static metadataFetchFailed(url: string, httpStatus: number): WidgetError;
236
+ static invalidUrl(url: string, reason: string): WidgetError;
237
+ static invalidMetadata(reason: string, originalError?: Error): WidgetError;
238
+ static actionError(actionIndex: number, reason: string): WidgetError;
239
+ /**
240
+ * Error when fetching the widget directory fails.
241
+ * @param url The URL that was fetched.
242
+ * @param httpStatus The HTTP status code received.
243
+ * @param statusText Optional status text from the response.
244
+ */
245
+ static directoryFetchFailed(url: string, httpStatus: number, statusText?: string): WidgetError;
246
+ /**
247
+ * Error when the fetched directory data has an invalid format.
248
+ * @param reason Description of why the format is invalid.
249
+ */
250
+ static invalidDirectoryFormat(reason: string): WidgetError;
251
+ /**
252
+ * Generic error during the directory refresh process.
253
+ * @param reason Description of the error.
254
+ * @param originalError The original error caught, if any.
255
+ */
256
+ static directoryRefreshError(reason: string, originalError?: Error): WidgetError;
257
+ }
258
+ /**
259
+ * Helper functions for error handling
260
+ */
261
+ declare const ErrorUtils: {
262
+ /**
263
+ * Safely wrap async operations with consistent error handling
264
+ */
265
+ safeAsync<T>(promise: Promise<T>, errorMapper?: (err: unknown) => RelayerError): Promise<T>;
266
+ };
267
+
268
+ declare const VERSION = "0.1.2";
269
+
270
+ export { API_REPOSITORY_URL, BlockchainError, type DirectoryData, type DirectoryInitializationConfig, ErrorUtils, type IntegratorDomain, InvalidOperationError, type MaliciousDomain, NetworkError, NotFoundError, PROXY_URL, type ProxifyResult, RelayerError, SecurityError, type Template, type TemplateCategory, type TemplateDirectory, VERSION, ValidationError, WidgetDirectory, type WidgetDirectoryConfig, type WidgetEntry, WidgetError, type WidgetSecurityState, addHexPrefix, clearClientKey, execute, formatNumber, getClientKey, getMetadata, proxify, removeHexPrefix, setClientKey, truncateAddress, truncateString };