arnacon-sdk
Version: 
A comprehensive SDK for deploying and managing Arnacon smart contracts across multiple networks
499 lines (426 loc) • 14.5 kB
JavaScript
const { ethers } = require("ethers");
const ContractFactoryLoader = require("./core/ContractFactoryLoader");
const DeploymentManager = require("./core/DeploymentManager");
const ServiceProviderManager = require("./service/ServiceProviderManager");
const IPFSManager = require("./utils/IPFSManager");
const BlockchainExplorer = require("./explorer/BlockchainExplorer");
const NetworkConfig = require("./utils/NetworkConfig");
class ArnaconSDK {
    constructor(privateKey, rpcUrlOrChainIdOrSigner) {
        this.privateKey = privateKey;
        this.networkConfig = new NetworkConfig();
        // Check if the second parameter is a signer object
        if (rpcUrlOrChainIdOrSigner && typeof rpcUrlOrChainIdOrSigner === 'object' && rpcUrlOrChainIdOrSigner.provider) {
            // It's a signer object
            this.signer = rpcUrlOrChainIdOrSigner;
            this.provider = this.signer.provider;
            
            // Try to get chainId from the provider
            this.chainId = null;
            this.rpcUrl = null;
            this.networkName = "Custom Network";
            
            // Get network info from provider if available
            this.initializeFromProvider();
        } else {
            // Determine if rpcUrlOrChainIdOrSigner is a chainId (number) or RPC URL (string)
            if (typeof rpcUrlOrChainIdOrSigner === 'number' || /^\d+$/.test(rpcUrlOrChainIdOrSigner.toString())) {
                // It's a chainId
                this.chainId = parseInt(rpcUrlOrChainIdOrSigner);
                this.rpcUrl = this.networkConfig.getRpcUrl(this.chainId);
                this.networkName = this.networkConfig.getNetworkName(this.chainId);
            } else {
                // It's an RPC URL (backward compatibility)
                this.rpcUrl = rpcUrlOrChainIdOrSigner;
                this.chainId = null;
                this.networkName = "Custom Network";
            }
            
            this.provider = null;
            this.signer = null;
            
            this.initializeProvider();
        }
        
        this.initializeManagers();
    }
    /**
     * Initialize the provider and signer
     */
    initializeProvider() {
        // Create provider from RPC URL
        this.provider = new ethers.providers.JsonRpcProvider(this.rpcUrl);
        this.signer = new ethers.Wallet(this.privateKey, this.provider);
    }
    /**
     * Initialize network information from an existing provider
     */
    initializeFromProvider() {
        // We'll set up the network info asynchronously after construction
        // For now, just set defaults
        this.chainId = null;
        this.networkName = "Custom Network";
        this.rpcUrl = "Custom RPC";
    }
    /**
     * Initialize network information asynchronously from provider
     * Call this method after construction to get proper network info
     */
    async initializeNetworkInfo() {
        try {
            if (this.provider && this.provider.getNetwork) {
                const network = await this.provider.getNetwork();
                this.chainId = network.chainId;
                this.networkName = this.networkConfig.getNetworkName(this.chainId) || network.name || "Custom Network";
                this.rpcUrl = this.networkConfig.getRpcUrl(this.chainId) || "Custom RPC";
            }
        } catch (error) {
            console.warn("Could not get network information from provider:", error.message);
            // Keep default values
        }
    }
    /**
     * Initialize all managers
     */
    initializeManagers() {
        // Initialize core components
        this.factoryLoader = new ContractFactoryLoader();
        this.deploymentManager = new DeploymentManager(this.signer, this.factoryLoader, this.chainId);
        
        // Initialize domain-specific managers
        this.serviceProvider = new ServiceProviderManager(this.deploymentManager);
        this.explorer = new BlockchainExplorer(this.deploymentManager);
        
        // Initialize utility managers
        this.ipfs = new IPFSManager();
    }
    // ===== DEPLOYMENT METHODS =====
    
    /**
     * Deploy all core contracts (ENS, Registrar, etc.)
     */
    async deployContracts(tld = "global") {
        return this.deploymentManager.deployContracts(tld);
    }
    /**
     * Deploy temp core contracts (ENS, Registrar, etc.)
     */
    async deployTempContracts(tld = "temp") {
        return this.deploymentManager.deployTempContracts(tld);
    }
    /**
     * Deploy email core contracts (ENS, Registrar, etc.)
     */
    async deployEmailContracts() {
        return this.deploymentManager.deployEmailContracts();
    }
    /**
     * Deploy GSM (Global Service Management) contracts
     */
    async deployGSM() {
        return this.deploymentManager.deployGSM();
    }
    // ===== SERVICE PROVIDER METHODS =====
    
    /**
     * Register as a service provider
     */
    async registerAsServiceProvider(name) {
        return this.serviceProvider.registerAsServiceProvider(name);
    }
    /**
     * Transfer ownership of all deployed contracts to a new owner
     */
    async transferAllOwnership(newOwnerAddress) {
        return this.deploymentManager.transferAllOwnership(newOwnerAddress);
    }
    /**
     * Make a wallet a controller in all NameWrapper contracts
     */
    async makeWrapperController(controllerAddress) {
        return this.deploymentManager.makeWrapperController(controllerAddress);
    }
    /**
     * Purchase a top-level domain name
     */
    async purchaseName(name, durationInDays = 365) {
        return this.serviceProvider.purchaseName(name, durationInDays);
    }
    /**
     * Purchase a top-level domain name
     */
    async purchaseNameETHController(name, durationInDays = 365) {
        return this.serviceProvider.purchaseNameETHController(name, durationInDays);
    }
    /**
     * Get second level controller for a service provider
     */
    async getSecondLevelController() {
        return this.serviceProvider.getSecondLevelController(this.signer.address);
    }
    /**
     * Get second level interactor for a service provider
     */
    async getSecondLevelInteractor() {
        return this.serviceProvider.getSecondLevelInteractor(this.signer.address);
    }
    /**
     * Get product type registry for a service provider and name
     */
    async getProductRegistry(name, spAddress = null) {
        return this.serviceProvider.getProductRegistry(spAddress || this.signer.address, name);
    }
    /**
     * Get product types from registry for a service provider and name
     */
    async getProductTypes(name, spAddress = null) {
        return this.serviceProvider.getProductTypes(spAddress || this.signer.address, name);
    }
    /**
     * Get all products with metadata from ProductTypeRegistry
     */
    async getAllProductTypesWithMetadata(name, spAddress = null) {
        return this.serviceProvider.getAllProductTypesWithMetadata(spAddress || this.signer.address, name);
    }
    /**
     * Get all products from a specific NFT contract
     */
    async getProductsFromContract(nftContractAddress) {
        return this.serviceProvider.getProductsFromContract(nftContractAddress);
    }
    /**
     * Get all products from all NFT contracts for a service provider and name
     */
    async getAllProducts(name, spAddress = null) {
        return this.serviceProvider.getAllProducts(spAddress || this.signer.address, name);
    }
    /**
     * Create provision and update resolver
     */
    async createProvisionAndUpdateResolver(key, tokenURI, name, identifier, spAddress = null) {
        return this.serviceProvider.createProvisionAndUpdateResolver(spAddress || this.signer.address, key, tokenURI, name, identifier);
    }
    /**
     * Create a text record
     */
    async createRecord(key, value, name, spAddress = null) {
        return this.serviceProvider.createRecord(spAddress || this.signer.address, key, value, name);
    }
    /**
     * Get a text record
     */
    async getRecord(key, name) {
        return this.serviceProvider.getRecord( key, name);
    }
    /**
     * Create a product type
     */
    async createProductType(name, productType, productInfo, spAddress = null) {
        return this.serviceProvider.createProductType(spAddress || this.signer.address, name, productType, productInfo);
    }
    /**
     * Deploy NFT contract and add it to the resolver
     */
    async deployNFTContract(name, spAddress = null) {
        return this.serviceProvider.deployNFTContract(spAddress || this.signer.address, name);
    }
    /**
     * Get NFT contracts for a service provider and name
     */
    async getNFTContracts(name, spAddress = null) {
        return this.serviceProvider.getNFTContracts(spAddress || this.signer.address, name);
    }
    /**
     * Create a product (mint and attach)
     */
    async createProduct(label, name, productInfo, productType, spAddress = null) {
        return this.serviceProvider.createProduct(spAddress || this.signer.address, label, name, productInfo, productType);
    }
    /**
     * Burn an NFT
     */
    async burnNFT(name, tokenId, spAddress = null) {
        return this.serviceProvider.burnNFT(spAddress || this.signer.address, name, tokenId);
    }
    /**
     * Batch create products
     */
    async batchCreateProduct(ens, productInfos, productTypes, spAddress = null) {
        return this.serviceProvider.batchCreateProduct(spAddress || this.signer.address, ens, productInfos, productTypes);
    }
    /**
     * Register a subdomain
     */
    async registerSubdomain(owner, label, name, spAddress = null) {
        return this.serviceProvider.registerSubdomain(spAddress || this.signer.address, owner, label, name);
    }
    // ===== BLOCKCHAIN EXPLORER METHODS =====
    
    /**
     * Get comprehensive data for an ENS name
     */
    async getData(ens) {
        return this.explorer.getData(ens);
    }
    /**
     * Get provision data from a name by traversing up the hierarchy
     */
    async getProvision(name, identifier) {
        return this.explorer.getProvision(`${name}.global`, identifier);
    }
    /**
     * Get expiry for a label from Base Registrar
     */
    async getExpiry(name) {
        return this.explorer.getExpiry(name);
    }
    /**
     * Get owner of an ENS name
     */
    async getEnsOwner(name) {
        return this.explorer.getEnsOwner(name);
    }
    /**
     * Get wrapped owner of an ENS name
     */
    async getWrapperOwner(name) {
        return this.explorer.getWrapperOwner(name);
    }
    /**
     * Get valid owner (handles both regular and wrapped names)
     */
    async getOwner(name) {
        return this.explorer.getOwner(name);
    }
    /**
     * Get names for a specific address
     */
    async getRegisteredNames() {
        const address = this.signer.address;
        return this.explorer.getRegisteredNames(address);
    }
    /**
     * Get resolver for an ENS name
     */
    async getResolver(ens) {
        return this.explorer.getResolver(ens);
    }
    /**
     * Get TTL for an ENS name
     */
    async getTTL(ens) {
        return this.explorer.getTTL(ens);
    }
    // ===== UTILITY METHODS =====
    
    /**
     * Upload metadata to IPFS
     */
    async uploadToIPFS(metadata) {
        return this.ipfs.uploadToIPFS(metadata);
    }
    /**
     * Fetch metadata from IPFS
     */
    async fetchFromIPFS(ipfsUri) {
        return this.ipfs.fetchFromIPFS(ipfsUri);
    }
    // ===== CONTRACT MANAGEMENT METHODS =====
    
    /**
     * Get contract address by name
     */
    getContractAddress(name) {
        return this.deploymentManager.getContractAddress(name);
    }
    /**
     * Get all deployed contract addresses
     */
    getAllContractAddresses() {
        return this.deploymentManager.getAllContractAddresses();
    }
    /**
     * Check if contract artifact exists
     */
    hasContract(contractName) {
        return this.deploymentManager.hasContract(contractName);
    }
    /**
     * Get contract factory for a specific contract
     */
    getContractFactory(contractName) {
        return this.deploymentManager.getContractFactory(contractName);
    }
    // ===== CONVENIENCE METHODS =====
    
    /**
     * Get the signer address
     */
    getSignerAddress() {
        return this.signer.address;
    }
    /**
     * Get the provider
     */
    getProvider() {
        return this.provider;
    }
    /**
     * Get the signer
     */
    getSigner() {
        return this.signer;
    }
    // ===== NETWORK INFORMATION METHODS =====
    
    /**
     * Get the current chainId
     */
    getChainId() {
        return this.chainId;
    }
    /**
     * Get the current network name
     */
    getNetworkName() {
        return this.networkName;
    }
    /**
     * Get the current RPC URL
     */
    getRpcUrl() {
        return this.rpcUrl;
    }
    /**
     * Get the explorer URL for the current network
     */
    getExplorerUrl() {
        if (this.chainId) {
            return this.networkConfig.getExplorerUrl(this.chainId);
        }
        return null;
    }
    /**
     * Get all supported chainIds
     */
    getSupportedChainIds() {
        return this.networkConfig.getSupportedChainIds();
    }
    /**
     * Get all network configurations
     */
    getAllNetworks() {
        return this.networkConfig.getAllNetworks();
    }
    /**
     * Get all products from all NFT contracts for a service provider and name (raw - no metadata fetching)
     */
    async getAllProductsRaw(name, spAddress = null) {
        return this.serviceProvider.getAllProductsRaw(spAddress || this.signer.address, name);
    }
    /**
     * Get tokenURI and owner for a specific token
     */
    async getTokenInfo(nftContractAddress, tokenId) {
        return this.serviceProvider.getTokenInfo(nftContractAddress, tokenId);
    }
    /**
     * Replace provision with new tokenURI
     */
    async replaceProvision(key, tokenURI, spAddress = null) {
        return this.serviceProvider.replaceProvision(spAddress || this.signer.address, key, tokenURI);
    }
    /**
     * Get all products from all specific NFT contract (raw - no metadata fetching)
     */
    async getProductsFromContractRaw(nftContractAddress) {
        return this.serviceProvider.getProductsFromContractRaw(nftContractAddress);
    }
}
module.exports = ArnaconSDK;