UNPKG

arnacon-sdk

Version:

A comprehensive SDK for deploying and managing Arnacon smart contracts across multiple networks

496 lines (375 loc) • 13.7 kB
# Arnacon SDK A comprehensive SDK for deploying and managing Arnacon smart contracts across multiple networks with ease. ## Installation ```bash npm install @arnacon/sdk ``` ## Quick Start ### Using ChainId (Recommended) ```javascript const ArnaconSDK = require('@arnacon/sdk'); // Initialize the SDK with your private key and chainId const privateKey = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; const chainId = 137; // Polygon mainnet const sdk = new ArnaconSDK(privateKey, chainId); // Get network information console.log("Network:", sdk.getNetworkName()); console.log("RPC URL:", sdk.getRpcUrl()); console.log("Explorer:", sdk.getExplorerUrl()); // Deploy all contracts with custom TLD await sdk.deployContracts("global"); // or any TLD you want await sdk.deployGSM(); await sdk.registerAsServiceProvider("mycompany"); ``` ### Using RPC URL (Backward Compatibility) ```javascript const ArnaconSDK = require('@arnacon/sdk'); // Initialize the SDK with your private key and RPC URL const privateKey = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; const rpcUrl = "https://polygon-rpc.com"; // or your preferred RPC endpoint const sdk = new ArnaconSDK(privateKey, rpcUrl); // Deploy all contracts with custom TLD await sdk.deployContracts("global"); // or any TLD you want await sdk.deployGSM(); await sdk.registerAsServiceProvider("mycompany"); ``` ## Supported Networks The SDK supports the following networks out of the box: | Chain ID | Network Name | RPC URL | Explorer | |----------|--------------|---------|----------| | 137 | Polygon | https://polygon-rpc.com | https://polygonscan.com | | 23295 | Oasis Sapphire | https://1rpc.io/oasis/sapphire | https://explorer.sapphire.oasis.dev | | 23294 | Oasis Sapphire Testnet | https://testnet.sapphire.oasis.dev | https://testnet.explorer.sapphire.oasis.dev | | 80002 | Polygon Amoy | https://rpc-amoy.polygon.technology | https://amoy.polygonscan.com | | 31337 | Hardhat Local | http://localhost:8545 | null | | 1337 | Testing Global | http://localhost:8545 | null | ## Features ### šŸš€ Deploy Functions #### `deployContracts(tld = "global")` Deploys all core contracts for the specified TLD (Top Level Domain) including: - ENS Registry - Base Registrar Implementation - Reverse Registrar - Static Metadata Service - Name Wrapper - Public Resolver - Simple Price Oracle - ETH Registrar Controller The TLD parameter allows you to deploy for any domain extension (e.g., "global", "test", "app", etc.). ```javascript // Deploy for .global TLD const contracts = await sdk.deployContracts("global"); console.log("Deployed contracts:", Object.keys(contracts)); // Deploy for .test TLD const contracts = await sdk.deployContracts("test"); console.log("Deployed contracts:", Object.keys(contracts)); // Deploy for .app TLD const contracts = await sdk.deployContracts("app"); console.log("Deployed contracts:", Object.keys(contracts)); ``` #### `deployGSM()` Deploys Global Service Management contracts: - Poseidon T3 Library - ETH Registrar Controller - Public Resolver - Name Wrapper - Global Registrar Controller - Provision Registry ```javascript const gsmContracts = await sdk.deployGSM(); console.log("GSM contracts deployed:", Object.keys(gsmContracts)); ``` #### `registerAsServiceProvider(name)` Registers as a service provider with the specified name: - Deploys required contracts - Sets up second level interactor - Configures Arnacon resolver - Deploys product type registry - Sets up NFT contracts ```javascript const serviceProviderInfo = await sdk.registerAsServiceProvider("mycompany"); console.log("Service provider info:", serviceProviderInfo); ``` ### šŸ‘¤ Service Provider Methods #### `getSecondLevelController()` Get the second level controller address for the current service provider. ```javascript const controller = await sdk.getSecondLevelController(); console.log("Second level controller:", controller); ``` #### `getSecondLevelInteractor()` Get the second level interactor address for the current service provider. ```javascript const interactor = await sdk.getSecondLevelInteractor(); console.log("Second level interactor:", interactor); ``` #### `getProductRegistry(name)` Get the product type registry contract for a specific name. ```javascript const registry = await sdk.getProductRegistry("mydomain"); console.log("Product type registry:", registry); ``` #### `getProductTypes(name)` Get all product types from the registry for a specific name. ```javascript const productTypes = await sdk.getProductTypes("mydomain"); console.log("Product types:", productTypes); ``` #### `getAllProductsWithMetadata(name)` Get all products with their full metadata from the ProductTypeRegistry. ```javascript const productsWithMetadata = await sdk.getAllProductsWithMetadata("mydomain"); console.log("Products with metadata:", productsWithMetadata); ``` #### `getProductsFromContract(nftContractAddress)` Get all products from a specific NFT contract. ```javascript const products = await sdk.getProductsFromContract("0x123..."); console.log("Products from contract:", products); ``` #### `getAllProducts(name)` Get all products from all NFT contracts for a service provider and name. ```javascript const allProducts = await sdk.getAllProducts("mydomain"); console.log("All products:", allProducts); ``` #### `createProvisionAndUpdateResolver(key, tokenURI, name, identifier)` Create a provision and update the resolver for a specific key and identifier. ```javascript const provisionInfo = { name: "Premium Service", description: "High-quality service package", price: "100" }; const result = await sdk.createProvisionAndUpdateResolver("service", provisionInfo, "mydomain", "premium"); console.log("Provision created:", result); ``` #### `createRecord(key, value, name)` Create a text record for a specific key and value. ```javascript const result = await sdk.createRecord("website", "https://example.com", "mydomain"); console.log("Record created:", result); ``` #### `createProductType(name, productType, productInfo)` Create a new product type in the registry. ```javascript const productInfo = { name: "Premium Service", description: "High-quality service package", price: "100", features: ["24/7 support", "Priority access"] }; await sdk.createProductType("mydomain", "premium", productInfo); ``` #### `deployNFTContract(name)` Deploy an NFT contract and add it to the resolver for a specific name. ```javascript const nftInfo = await sdk.deployNFTContract("mydomain"); console.log("NFT contract deployed:", nftInfo.nftContractAddress); ``` #### `getNFTContracts(name)` Get all NFT contracts associated with a specific name. ```javascript const nftContracts = await sdk.getNFTContracts("mydomain"); console.log("NFT contracts:", nftContracts); ``` #### `createProduct(ens, productInfo, productType)` Create a product by minting an NFT and attaching it to the resolver. ```javascript const productInfo = { name: "Product 1", description: "Description of product 1" }; const result = await sdk.createProduct("mydomain.global", productInfo, "standard"); console.log("Product created:", result); ``` #### `batchCreateProduct(ens, productInfos, productTypes)` Batch create multiple products at once. ```javascript const productInfos = [ { name: "Product 1", description: "Description 1" }, { name: "Product 2", description: "Description 2" } ]; const productTypes = ["standard", "premium"]; const results = await sdk.batchCreateProduct("mydomain.global", productInfos, productTypes); console.log("Products created:", results); ``` #### `registerSubdomain(owner, label, name)` Register a subdomain for a specific owner. ```javascript const result = await sdk.registerSubdomain("0x123...", "api", "mydomain"); console.log("Subdomain registered:", result); ``` ### �� Utility Functions #### `getContractAddress(name)` Get the address of a specific deployed contract. ```javascript const ensAddress = sdk.getContractAddress("ENSRegistry"); console.log("ENS Registry:", ensAddress); ``` #### `getAllContractAddresses()` Get all deployed contract addresses. ```javascript const allAddresses = sdk.getAllContractAddresses(); console.log("All addresses:", allAddresses); ``` ### 🌐 Network Information Methods #### `getChainId()` Get the current chainId. ```javascript const chainId = sdk.getChainId(); console.log("Chain ID:", chainId); ``` #### `getNetworkName()` Get the current network name. ```javascript const networkName = sdk.getNetworkName(); console.log("Network:", networkName); ``` #### `getRpcUrl()` Get the current RPC URL. ```javascript const rpcUrl = sdk.getRpcUrl(); console.log("RPC URL:", rpcUrl); ``` #### `getExplorerUrl()` Get the explorer URL for the current network. ```javascript const explorerUrl = sdk.getExplorerUrl(); console.log("Explorer:", explorerUrl); ``` #### `getSupportedChainIds()` Get all supported chainIds. ```javascript const supportedChainIds = sdk.getSupportedChainIds(); console.log("Supported networks:", supportedChainIds); ``` #### `getAllNetworks()` Get all network configurations. ```javascript const allNetworks = sdk.getAllNetworks(); console.log("All networks:", allNetworks); ``` ## TLD Support The SDK supports any TLD (Top Level Domain) you specify. The TLD is automatically hashed to generate the correct node and label for ENS registration. ### Examples: ```javascript // Deploy for .global await sdk.deployContracts("global"); // Deploy for .test await sdk.deployContracts("test"); // Deploy for .app await sdk.deployContracts("app"); // Deploy for .company await sdk.deployContracts("company"); // Deploy for .local await sdk.deployContracts("local"); ``` ### TLD Hashing The SDK automatically: 1. Uses `namehash.hash(tld)` to generate the TLD node 2. Uses `keccak256(tld)` to generate the TLD label 3. Sets up the base registrar as the owner of the TLD 4. Configures all contracts to work with the specified TLD ## RPC URL Support The SDK works with any Ethereum RPC endpoint. Here are some common examples: ### Local Development ```javascript const sdk = new ArnaconSDK(privateKey, "http://localhost:8545"); ``` ### Test Networks ```javascript // Sepolia const sdk = new ArnaconSDK(privateKey, "https://sepolia.infura.io/v3/YOUR_PROJECT_ID"); // Goerli const sdk = new ArnaconSDK(privateKey, "https://goerli.infura.io/v3/YOUR_PROJECT_ID"); ``` ### Mainnet ```javascript const sdk = new ArnaconSDK(privateKey, "https://mainnet.infura.io/v3/YOUR_PROJECT_ID"); ``` ### Other Providers ```javascript // Alchemy const sdk = new ArnaconSDK(privateKey, "https://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY"); // QuickNode const sdk = new ArnaconSDK(privateKey, "https://your-endpoint.quiknode.pro/YOUR_API_KEY/"); ``` ## Environment Variables Set these environment variables for IPFS functionality: ```bash export PINATA_JWT_TOKEN="your_pinata_jwt_token" # For IPFS uploads ``` ## Contract Address Storage The SDK automatically saves deployed contract addresses to `deployed-addresses.json`. This allows you to: - Reuse deployed contracts across sessions - Avoid redeploying existing contracts - Track all deployments for your RPC endpoint ## Gas Optimization The SDK includes automatic gas estimation with: - 20% buffer on gas estimates - Fallback gas limits for failed estimations - Configurable priority and max fees (25 gwei priority, 50 gwei max) - Transaction execution with proper error handling ## Error Handling All functions include comprehensive error handling: ```javascript try { await sdk.deployContracts("global"); } catch (error) { console.error("Deployment failed:", error.message); } ``` ## Example Usage See `example.js` for complete usage examples including: - Full deployment workflow with custom TLDs - Step-by-step deployment - Contract address retrieval - Error handling - Multi-network deployment examples - Multiple TLD deployment examples ## Running Examples ```bash # Run the main example node example.js # Or import and use specific functions const { main, deployStepByStep, deployWithDifferentTLDs } = require('./example'); await main(); ``` ## Key Differences from deploy.js This SDK is designed to work independently of the hardhat runtime environment: 1. **Direct ethers usage**: Uses ethers v5.8.0 directly instead of hardhat's ethers 2. **RPC URL initialization**: Takes RPC URL directly instead of network names 3. **Contract factory creation**: Uses `ethers.getContractFactory()` directly 4. **Provider management**: Creates JsonRpcProvider from RPC URL 5. **Address storage**: Uses generic `deployed-addresses.json` file 6. **TLD flexibility**: Accepts any TLD parameter instead of hardcoded "global" ## Architecture The SDK is built with a clean, modular architecture: ``` ArnaconSDK ā”œā”€ā”€ Constructor (privateKey, rpcUrl) ā”œā”€ā”€ Provider/Signer initialization ā”œā”€ā”€ Contract management ā”œā”€ā”€ Deploy functions │ ā”œā”€ā”€ deployContracts(tld) │ ā”œā”€ā”€ deployGSM() │ └── registerAsServiceProvider() ā”œā”€ā”€ Utility functions │ ā”œā”€ā”€ getContractAddress() │ └── getAllContractAddresses() └── Helper functions ā”œā”€ā”€ deployIfNeeded() ā”œā”€ā”€ getGasSettings() └── executeTransaction() ``` ## Contributing When adding new functionality to the SDK: 1. Follow the existing code structure 2. Include proper JSDoc comments 3. Add error handling 4. Update the README with new functions 5. Add examples to `example.js` 6. Ensure compatibility with ethers v5.8.0 ## License This SDK is part of the Arnacon project.