#!/usr/bin/env bun
/**
 * Request testnet tokens from Coinbase faucet for accounts with faucet metadata
 *
 * Usage:
 *   bun node_modules/alchemy/src/coinbase/faucet.ts              # Fund all accounts with faucet config
 *   bun node_modules/alchemy/src/coinbase/faucet.ts dev          # Fund only accounts in dev scope
 *   bun node_modules/alchemy/src/coinbase/faucet.ts backend/dev  # Fund specific scope
 */
import { glob } from "glob";
import { access, readFile } from "node:fs/promises";
import { join } from "pathe";
import { createCdpClient } from "./client.js";
// Track funded combinations to avoid duplicates within this run
const funded = new Set();
// Get optional scope argument
const scope = process.argv[2];
// Initialize CDP client (uses CDP_* env vars automatically)
const cdp = await createCdpClient();
let stateFiles;
if (scope) {
    // If scope provided, find matching directories
    const scopePath = join(".alchemy", scope);
    let scopeExists = false;
    try {
        await access(scopePath);
        scopeExists = true;
    }
    catch {
        scopeExists = false;
    }
    if (scopeExists) {
        // Exact match found
        console.log(`Using scope: ${scope}`);
        stateFiles = await glob("*.json", {
            cwd: scopePath,
            absolute: true,
        });
    }
    else {
        // Try to find directories that end with the provided scope
        // We need to find directories, so we'll look for JSON files and extract the directory paths
        const allFiles = await glob(`**/${scope}/*.json`, {
            cwd: ".alchemy",
        });
        // Extract unique directory paths
        const possibleScopes = [
            ...new Set(allFiles.map((f) => f.replace(/\/[^/]+\.json$/, ""))),
        ];
        if (possibleScopes.length === 0) {
            console.error(`No scope found matching: ${scope}`);
            process.exit(1);
        }
        else if (possibleScopes.length === 1) {
            // Found exactly one match
            const foundScope = possibleScopes[0];
            console.log(`Using scope: ${foundScope}`);
            stateFiles = await glob("*.json", {
                cwd: join(".alchemy", foundScope),
                absolute: true,
            });
        }
        else {
            // Multiple matches found - use all of them
            console.log(`Found ${possibleScopes.length} scopes matching '${scope}':`);
            for (const s of possibleScopes) {
                console.log(`  - ${s}`);
            }
            // Collect state files from all matching scopes
            stateFiles = [];
            for (const foundScope of possibleScopes) {
                const files = await glob("*.json", {
                    cwd: join(".alchemy", foundScope),
                    absolute: true,
                });
                stateFiles.push(...files);
            }
        }
    }
}
else {
    // No scope provided, search all .alchemy subdirectories
    console.log("Searching all scopes for accounts with faucet configuration...");
    stateFiles = await glob("**/*.json", {
        cwd: ".alchemy",
        absolute: true,
    });
}
const allStates = (await Promise.all(stateFiles.map(async (file) => {
    try {
        const content = await readFile(file, "utf-8");
        return JSON.parse(content);
    }
    catch {
        return null;
    }
}))).filter(Boolean);
const accounts = allStates
    .filter((state) => state?.kind?.startsWith("coinbase::evm") &&
    state.output &&
    state.output.faucet)
    .map((state) => {
    const output = state.output;
    return {
        address: output.address,
        name: output.name,
        faucet: output.faucet,
    };
});
if (accounts.length === 0) {
    console.log("No accounts with faucet configuration found");
    process.exit(0);
}
console.log(`Found ${accounts.length} accounts with faucet configuration\n`);
for (const account of accounts) {
    console.log(`Account: ${account.name} (${account.address})`);
    for (const [network, tokens] of Object.entries(account.faucet)) {
        for (const token of tokens) {
            const key = `${account.address}-${network}-${token}`;
            // Skip if already processed in this run
            if (funded.has(key)) {
                console.log(`  ⏭️  Skipping ${token} on ${network} (already requested)`);
                continue;
            }
            // Request tokens from faucet
            try {
                console.log(`  💧 Requesting ${token} on ${network}...`);
                const response = await cdp.evm.requestFaucet({
                    address: account.address,
                    network: network,
                    token: token,
                });
                console.log(`  ✅ Funded: ${response.transactionHash}`);
                funded.add(key);
                // Small delay to avoid rate limits
                await new Promise((resolve) => setTimeout(resolve, 1000));
            }
            catch (error) {
                console.log(`  ❌ Error funding ${token} on ${network}: ${error.message}`);
            }
        }
    }
    console.log();
}
console.log("✨ Funding complete!");
//# sourceMappingURL=faucet.js.map