UNPKG

@fairmint/canton-node-sdk

Version:
300 lines 13 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.EnvLoader = void 0; const dotenv_1 = require("dotenv"); const path = __importStar(require("path")); const fs = __importStar(require("fs")); const errors_1 = require("../errors"); // Load environment variables with fallback to parent directory const currentEnvPath = '.env'; const parentEnvPath = path.join('..', '.env'); // Try to load from current directory first let result = (0, dotenv_1.config)({ path: currentEnvPath }); // If no .env file found in current directory, try parent directory if (result.error && fs.existsSync(parentEnvPath)) { result = (0, dotenv_1.config)({ path: parentEnvPath }); if (result.error) { console.warn('Failed to load .env file from parent directory:', result.error.message); } } /** Singleton class for managing environment variables and configuration */ class EnvLoader { constructor(options = {}) { this.env = process.env; this.options = options; } static getInstance(options = {}) { if (!EnvLoader.instance) { EnvLoader.instance = new EnvLoader(options); } else if (options.currentNetwork || options.currentProvider) { // Update existing instance with new options EnvLoader.instance.options = { ...EnvLoader.instance.options, ...options }; } return EnvLoader.instance; } static resetInstance() { EnvLoader.instance = undefined; } /** * Get configuration for a specific API type from environment variables * @param apiType The API type to get configuration for * @param options Optional network and provider to use instead of reading from env * @returns ClientConfig with only the specified API configured */ static getConfig(apiType, options) { const envLoader = EnvLoader.getInstance(); const network = options?.network || envLoader.getCurrentNetwork(); // For Lighthouse API, provider is optional let provider; let authUrl; if (apiType === 'LIGHTHOUSE_API') { // Lighthouse API doesn't require provider or auth URL } else { provider = options?.provider || envLoader.getCurrentProvider(); authUrl = envLoader.getAuthUrl(network, provider); } // Get API-specific configuration const apiConfig = envLoader.loadApiConfig(apiType, network, provider || undefined); if (!apiConfig) { if (apiType === 'LIGHTHOUSE_API') { throw new errors_1.ConfigurationError(`Missing required environment variable for ${apiType}. ` + `Required: CANTON_${network.toUpperCase()}_${apiType.toUpperCase()}_URI`); } else { const providerStr = provider ? provider.toUpperCase() : 'PROVIDER'; throw new errors_1.ConfigurationError(`Missing required environment variables for ${apiType}. ` + `Required: CANTON_${network.toUpperCase()}_${providerStr}_${apiType.toUpperCase()}_URI, ` + `CANTON_${network.toUpperCase()}_${providerStr}_${apiType.toUpperCase()}_CLIENT_ID, ` + `and either CLIENT_SECRET (for client_credentials) or USERNAME/PASSWORD (for password grant)`); } } const config = { network, apis: { [apiType]: apiConfig, }, }; // Only add provider and authUrl if they exist if (provider) { config.provider = provider; } if (authUrl) { config.authUrl = authUrl; } return config; } getNodeEnv() { const value = this.env['NODE_ENV'] || 'development'; if (!['development', 'production', 'test'].includes(value)) { throw new errors_1.ConfigurationError(`Invalid NODE_ENV: ${value}. Must be 'development', 'production', or 'test'`); } return value; } getCurrentNetwork() { if (this.options.currentNetwork) { return this.options.currentNetwork; } const value = this.env['CANTON_CURRENT_NETWORK']?.toLowerCase(); if (!value || !['devnet', 'testnet', 'mainnet'].includes(value)) { throw new errors_1.ConfigurationError('Missing or invalid CANTON_CURRENT_NETWORK. Must be "devnet", "testnet", or "mainnet"'); } return value; } getCurrentProvider() { if (this.options.currentProvider) { return this.options.currentProvider; } const value = this.env['CANTON_CURRENT_PROVIDER']?.toLowerCase(); if (!value) { throw new errors_1.ConfigurationError('Missing or invalid CANTON_CURRENT_PROVIDER'); } return value; } getApiUri(apiType, network, provider) { const targetNetwork = network || this.getCurrentNetwork(); // Special case for APIs that don't require provider-specific configuration if (apiType === 'LIGHTHOUSE_API') { const envKey = `CANTON_${targetNetwork.toUpperCase()}_${apiType.toUpperCase()}_URI`; const uri = this.env[envKey]; return uri; } const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_${apiType.toUpperCase()}_URI`; const uri = this.env[envKey]; return uri; } getApiClientId(apiType, network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_${apiType.toUpperCase()}_CLIENT_ID`; return this.env[envKey]; } getApiClientSecret(apiType, network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_${apiType.toUpperCase()}_CLIENT_SECRET`; return this.env[envKey]; } getApiUsername(apiType, network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_${apiType.toUpperCase()}_USERNAME`; return this.env[envKey]; } getApiPassword(apiType, network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_${apiType.toUpperCase()}_PASSWORD`; return this.env[envKey]; } getAuthUrl(network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_AUTH_URL`; const authUrl = this.env[envKey]; if (!authUrl) { throw new errors_1.ConfigurationError(`Missing required environment variable: ${envKey}`); } return authUrl; } getPartyId(network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_PARTY_ID`; const partyId = this.env[envKey]; if (!partyId) { throw new errors_1.ConfigurationError(`Missing required environment variable: ${envKey}`); } return partyId; } getUserId(network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_USER_ID`; return this.env[envKey]; } getDatabaseUrl(network) { const targetNetwork = network || this.getCurrentNetwork(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_DATABASE_URL`; const databaseUrl = this.env[envKey]; if (!databaseUrl) { throw new errors_1.ConfigurationError(`Missing required environment variable: ${envKey}`); } return databaseUrl; } getManagedParties(network, provider) { const targetNetwork = network || this.getCurrentNetwork(); const targetProvider = provider || this.getCurrentProvider(); const envKey = `CANTON_${targetNetwork.toUpperCase()}_${targetProvider.toUpperCase()}_MANAGED_PARTIES`; const managedParties = this.env[envKey]; if (!managedParties) { return []; } return managedParties.split(',').map(party => party.trim()).filter(party => party.length > 0); } loadApiConfig(apiType, network, provider) { const apiUrl = this.getApiUri(apiType, network, provider); // Special case for APIs that don't require authentication if (apiType === 'LIGHTHOUSE_API') { if (!apiUrl) { return undefined; } const lighthouseConfig = { apiUrl, }; // Lighthouse API doesn't require party ID at client level // Party ID will be provided in individual API calls return lighthouseConfig; } if (!provider) { return undefined; // Non-Lighthouse APIs require a provider } const clientId = this.getApiClientId(apiType, network, provider); const clientSecret = this.getApiClientSecret(apiType, network, provider); const username = this.getApiUsername(apiType, network, provider); const password = this.getApiPassword(apiType, network, provider); const partyId = this.getPartyId(network, provider); const userId = this.getUserId(network, provider); if (!apiUrl || !clientId) { return undefined; } // Determine grant type based on available credentials let grantType; let auth; if (clientSecret) { // Use client_credentials if client secret is available grantType = 'client_credentials'; auth = { grantType, clientId: clientId || '', clientSecret, }; } else if (username && password) { // Use password grant if username and password are available grantType = 'password'; auth = { grantType, clientId: clientId || '', username, password, }; } else { // Fallback to client_credentials without secret (some providers may not require it) grantType = 'client_credentials'; auth = { grantType, clientId: clientId || '', }; } const apiConfig = { apiUrl: apiUrl || '', auth, }; if (partyId) { apiConfig.partyId = String(partyId); } if (userId) { apiConfig.userId = String(userId); } return apiConfig; } } exports.EnvLoader = EnvLoader; //# sourceMappingURL=EnvLoader.js.map