1import * as fs from 'fs';
2import * as path from 'path';
3import * as os from 'os';
4import yaml from 'js-yaml';
5
6export interface Config {
7 privateKey?: string;
8 network?: string;
9 networks?: {
10 [network: string]: {
11 schemaUID?: string;
12 rpcUrl?: string;
13 easContractAddress?: string;
14 schemaRegistryAddress?: string;
15 };
16 };
17}
18
19/**
20 * Load config from multiple sources (priority order):
21 * 1. Custom config path (--config flag)
22 * 2. ./.atnotary.yaml (current directory)
23 * 3. ~/.atnotary.yaml (home directory)
24 * 4. .env file (fallback)
25 */
26export function loadConfig(customPath?: string): Config {
27 let config: Config = {};
28
29 // Try custom path first
30 if (customPath) {
31 if (fs.existsSync(customPath)) {
32 config = loadYamlConfig(customPath);
33 return config;
34 } else {
35 throw new Error(`Config file not found: ${customPath}`);
36 }
37 }
38
39 // Try current directory
40 const localConfig = path.join(process.cwd(), '.atnotary.yaml');
41 if (fs.existsSync(localConfig)) {
42 config = loadYamlConfig(localConfig);
43 return config;
44 }
45
46 // Try home directory
47 const homeConfig = path.join(os.homedir(), '.atnotary.yaml');
48 if (fs.existsSync(homeConfig)) {
49 config = loadYamlConfig(homeConfig);
50 return config;
51 }
52
53 return config;
54}
55
56function loadYamlConfig(filePath: string): Config {
57 try {
58 const fileContents = fs.readFileSync(filePath, 'utf8');
59 const config = yaml.load(fileContents) as Config;
60 return config;
61 } catch (error: any) {
62 throw new Error(`Failed to load config from ${filePath}: ${error.message}`);
63 }
64}
65
66/**
67 * Get schema UID for specific network
68 */
69export function getSchemaUID(config: Config, network: string): string | undefined {
70 return config.networks?.[network]?.schemaUID;
71}
72
73/**
74 * Create default config template
75 */
76export function createConfigTemplate(outputPath: string): void {
77 const template = `# atnotary configuration
78# Private key for signing transactions (required for notarization)
79privateKey: "0x..."
80
81# Default network (sepolia, base-sepolia, base)
82network: sepolia
83
84# Network-specific configuration
85networks:
86 sepolia:
87 schemaUID: "0x..."
88 # Optional: custom RPC URL
89 # rpcUrl: "https://..."
90
91 base-sepolia:
92 schemaUID: "0x..."
93 # rpcUrl: "https://sepolia.base.org"
94
95 base:
96 schemaUID: "0x..."
97 # rpcUrl: "https://mainnet.base.org"
98`;
99
100 fs.writeFileSync(outputPath, template, 'utf8');
101}