UNPKG

@cryptodevops/n8n-nodes-blockchain-explorer

Version:

n8n node for accessing multiple blockchain networks (Ethereum, BSC, Polygon, Fantom, Avalanche, Arbitrum, Optimism, etc.) with comprehensive analytics and data retrieval capabilities

737 lines (736 loc) 30.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.BlockchainExplorer = void 0; const n8n_workflow_1 = require("n8n-workflow"); const axios_1 = __importDefault(require("axios")); const BlockchainExplorerApi_credentials_1 = require("../../credentials/BlockchainExplorerApi.credentials"); class BlockchainExplorer { constructor() { this.description = { displayName: 'Blockchain Explorer', name: 'blockchainExplorer', icon: 'file:blockchain-explorer.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["network"] + " - " + $parameter["operation"] + ": " + $parameter["resource"]}}', description: 'Interact with multiple blockchain networks via their explorer APIs (Etherscan-compatible)', defaults: { name: 'Blockchain Explorer', }, inputs: ["main" /* NodeConnectionType.Main */], outputs: ["main" /* NodeConnectionType.Main */], credentials: [ { name: 'blockchainExplorerApi', required: true, }, ], properties: [ { displayName: 'Network', name: 'network', type: 'options', noDataExpression: true, options: [ { name: 'Arbitrum', value: 'arbitrum', }, { name: 'Avalanche', value: 'avalanche', }, { name: 'Binance Smart Chain', value: 'bsc', }, { name: 'Celo', value: 'celo', }, { name: 'Cronos', value: 'cronos', }, { name: 'Ethereum', value: 'ethereum', }, { name: 'Fantom', value: 'fantom', }, { name: 'Moonbeam', value: 'moonbeam', }, { name: 'Optimism', value: 'optimism', }, { name: 'Polygon', value: 'polygon', }, ], default: 'ethereum', description: 'The blockchain network to query', }, { displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options: [ { name: 'Account', value: 'account', }, { name: 'Block', value: 'block', }, { name: 'Contract', value: 'contract', }, { name: 'Gas', value: 'gas', }, { name: 'Stat', value: 'stats', }, { name: 'Token', value: 'token', }, { name: 'Transaction', value: 'transaction', }, ], default: 'account', }, // Account Operations { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['account'], }, }, options: [ { name: 'Get Balance', value: 'getBalance', description: 'Get native token balance for a single address', action: 'Get native token balance', }, { name: 'Get Balance Multi', value: 'getBalanceMulti', description: 'Get native token balance for multiple addresses', action: 'Get native token balance for multiple addresses', }, { name: 'Get Internal Transactions', value: 'getInternalTxs', description: 'Get list of internal transactions by address', action: 'Get internal transactions', }, { name: 'Get NFT Transfers', value: 'getTokenNftTx', description: 'Get list of NFT token transfer events by address', action: 'Get NFT transfers', }, { name: 'Get Normal Transactions', value: 'getNormalTxs', description: 'Get list of normal transactions by address', action: 'Get normal transactions', }, { name: 'Get Token Transfers', value: 'getTokenTx', description: 'Get list of token transfer events by address', action: 'Get token transfers', }, ], default: 'getBalance', }, // Block Operations { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['block'], }, }, options: [ { name: 'Get Block Reward', value: 'getBlockReward', description: 'Get block and uncle rewards by block number', action: 'Get block reward', }, { name: 'Get Block Number by Timestamp', value: 'getBlockNumberByTime', description: 'Get estimated block number by Unix timestamp', action: 'Get block number by timestamp', }, { name: 'Get Block by Number', value: 'getBlockByNumber', description: 'Get block details by block number', action: 'Get block by number', }, ], default: 'getBlockReward', }, // Contract Operations { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['contract'], }, }, options: [ { name: 'Get ABI', value: 'getAbi', description: 'Get contract ABI for verified contract source codes', action: 'Get contract ABI', }, { name: 'Get Source Code', value: 'getSourceCode', description: 'Get contract source code for verified contracts', action: 'Get contract source code', }, { name: 'Verify Contract', value: 'verifyContract', description: 'Verify and publish contract source code', action: 'Verify contract', }, ], default: 'getAbi', }, // Gas Operations { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['gas'], }, }, options: [ { name: 'Get Gas Oracle', value: 'getGasOracle', description: 'Get gas oracle data', action: 'Get gas oracle', }, { name: 'Get Gas Price', value: 'getGasPrice', description: 'Get current gas price', action: 'Get gas price', }, ], default: 'getGasOracle', }, // Stats Operations { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['stats'], }, }, options: [ { name: 'Get Token Supply', value: 'getTokenSupply', description: 'Get total supply of native token', action: 'Get token supply', }, { name: 'Get Token Price', value: 'getTokenPrice', description: 'Get latest native token price', action: 'Get token price', }, { name: 'Get Chain Stats', value: 'getChainStats', description: 'Get blockchain statistics', action: 'Get chain stats', }, ], default: 'getTokenSupply', }, // Token Operations { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['token'], }, }, options: [ { name: 'Get Token Supply', value: 'getTokenSupply', description: 'Get token total supply by contract address', action: 'Get token supply', }, { name: 'Get Token Balance', value: 'getTokenBalance', description: 'Get token account balance by contract address', action: 'Get token balance', }, { name: 'Get Token Info', value: 'getTokenInfo', description: 'Get token information by contract address', action: 'Get token info', }, ], default: 'getTokenSupply', }, // Transaction Operations { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, displayOptions: { show: { resource: ['transaction'], }, }, options: [ { name: 'Get Transaction Status', value: 'getTxReceiptStatus', description: 'Get transaction execution status', action: 'Get transaction status', }, { name: 'Get Transaction Receipt', value: 'getTxReceipt', action: 'Get transaction receipt', }, ], default: 'getTxReceiptStatus', }, // Common Parameters { displayName: 'Address', name: 'address', type: 'string', required: true, displayOptions: { show: { operation: [ 'getBalance', 'getNormalTxs', 'getInternalTxs', 'getTokenTx', 'getTokenNftTx', 'getTokenBalance', ], }, }, default: '', placeholder: '0x...', description: 'The blockchain address to query', }, { displayName: 'Addresses', name: 'addresses', type: 'string', required: true, displayOptions: { show: { operation: ['getBalanceMulti'], }, }, default: '', placeholder: '0x...,0x...', description: 'Comma-separated list of addresses (max 20)', }, { displayName: 'Contract Address', name: 'contractAddress', type: 'string', required: true, displayOptions: { show: { operation: [ 'getAbi', 'getSourceCode', 'verifyContract', 'getTokenSupply', 'getTokenBalance', 'getTokenInfo', ], }, }, default: '', placeholder: '0x...', description: 'The contract address to query', }, { displayName: 'Transaction Hash', name: 'txHash', type: 'string', required: true, displayOptions: { show: { operation: ['getTxReceiptStatus', 'getTxReceipt'], }, }, default: '', placeholder: '0x...', description: 'The transaction hash to query', }, { displayName: 'Block Number', name: 'blockNumber', type: 'string', required: true, displayOptions: { show: { operation: ['getBlockReward', 'getBlockByNumber'], }, }, default: '', placeholder: '12345678', description: 'The block number to query', }, { displayName: 'Timestamp', name: 'timestamp', type: 'string', required: true, displayOptions: { show: { operation: ['getBlockNumberByTime'], }, }, default: '', placeholder: '1578638524', description: 'Unix timestamp', }, { displayName: 'Start Block', name: 'startBlock', type: 'string', displayOptions: { show: { operation: ['getNormalTxs', 'getInternalTxs', 'getTokenTx', 'getTokenNftTx'], }, }, default: '0', description: 'Starting block number (0 for earliest)', }, { displayName: 'End Block', name: 'endBlock', type: 'string', displayOptions: { show: { operation: ['getNormalTxs', 'getInternalTxs', 'getTokenTx', 'getTokenNftTx'], }, }, default: '99999999', description: 'Ending block number (99999999 for latest)', }, { displayName: 'Page', name: 'page', type: 'number', displayOptions: { show: { operation: ['getNormalTxs', 'getInternalTxs', 'getTokenTx', 'getTokenNftTx'], }, }, default: 1, description: 'Page number for pagination', }, { displayName: 'Offset', name: 'offset', type: 'number', displayOptions: { show: { operation: ['getNormalTxs', 'getInternalTxs', 'getTokenTx', 'getTokenNftTx'], }, }, default: 10, description: 'Number of transactions to return (max 10000)', }, { displayName: 'Sort', name: 'sort', type: 'options', displayOptions: { show: { operation: ['getNormalTxs', 'getInternalTxs', 'getTokenTx', 'getTokenNftTx'], }, }, options: [ { name: 'Ascending', value: 'asc', }, { name: 'Descending', value: 'desc', }, ], default: 'asc', description: 'Sort order', }, ], }; } async execute() { const items = this.getInputData(); const returnData = []; const nodeInstance = this.getNode(); for (let i = 0; i < items.length; i++) { try { const credentials = await this.getCredentials('blockchainExplorerApi'); const network = this.getNodeParameter('network', i); const resource = this.getNodeParameter('resource', i); const operation = this.getNodeParameter('operation', i); // Get base URL let baseUrl = credentials.customBaseUrl; if (!baseUrl) { baseUrl = BlockchainExplorerApi_credentials_1.BlockchainExplorerApi.getBaseUrl(credentials.network, credentials.environment); } // Build API parameters const params = { apikey: credentials.apiKey, }; // Set module and action based on resource and operation BlockchainExplorer.setModuleAndAction(params, resource, operation); // Add operation-specific parameters BlockchainExplorer.addOperationParameters(this, params, operation, i); // Make API request const response = await axios_1.default.get(baseUrl, { params }); if (response.data.status === '0' && response.data.message !== 'OK') { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `API Error: ${response.data.result || response.data.message}`, { itemIndex: i }); } returnData.push({ json: { network, resource, operation, ...response.data, }, pairedItem: { item: i }, }); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message }, pairedItem: { item: i }, }); continue; } throw error; } } return [returnData]; } static setModuleAndAction(params, resource, operation) { switch (resource) { case 'account': params.module = 'account'; switch (operation) { case 'getBalance': params.action = 'balance'; break; case 'getBalanceMulti': params.action = 'balancemulti'; break; case 'getNormalTxs': params.action = 'txlist'; break; case 'getInternalTxs': params.action = 'txlistinternal'; break; case 'getTokenTx': params.action = 'tokentx'; break; case 'getTokenNftTx': params.action = 'tokennfttx'; break; } break; case 'block': params.module = 'block'; switch (operation) { case 'getBlockReward': params.action = 'getblockreward'; break; case 'getBlockNumberByTime': params.action = 'getblocknobytime'; break; case 'getBlockByNumber': params.action = 'getblockbynumber'; break; } break; case 'contract': params.module = 'contract'; switch (operation) { case 'getAbi': params.action = 'getabi'; break; case 'getSourceCode': params.action = 'getsourcecode'; break; case 'verifyContract': params.action = 'verifysourcecode'; break; } break; case 'gas': params.module = 'gastracker'; switch (operation) { case 'getGasOracle': params.action = 'gasoracle'; break; case 'getGasPrice': params.action = 'gasprice'; break; } break; case 'stats': params.module = 'stats'; switch (operation) { case 'getTokenSupply': params.action = 'ethsupply'; break; case 'getTokenPrice': params.action = 'ethprice'; break; case 'getChainStats': params.action = 'chainsize'; break; } break; case 'token': params.module = 'stats'; switch (operation) { case 'getTokenSupply': params.action = 'tokensupply'; break; case 'getTokenBalance': params.module = 'account'; params.action = 'tokenbalance'; break; case 'getTokenInfo': params.action = 'tokeninfo'; break; } break; case 'transaction': params.module = 'transaction'; switch (operation) { case 'getTxReceiptStatus': params.action = 'gettxreceiptstatus'; break; case 'getTxReceipt': params.action = 'gettxreceipt'; break; } break; } } static addOperationParameters(executeFunctions, params, operation, itemIndex) { switch (operation) { case 'getBalance': case 'getNormalTxs': case 'getInternalTxs': case 'getTokenTx': case 'getTokenNftTx': params.address = executeFunctions.getNodeParameter('address', itemIndex); break; case 'getBalanceMulti': params.address = executeFunctions.getNodeParameter('addresses', itemIndex); params.tag = 'latest'; break; case 'getTokenBalance': params.address = executeFunctions.getNodeParameter('address', itemIndex); params.contractaddress = executeFunctions.getNodeParameter('contractAddress', itemIndex); params.tag = 'latest'; break; case 'getAbi': case 'getSourceCode': case 'verifyContract': case 'getTokenSupply': case 'getTokenInfo': params.address = executeFunctions.getNodeParameter('contractAddress', itemIndex); break; case 'getTxReceiptStatus': case 'getTxReceipt': params.txhash = executeFunctions.getNodeParameter('txHash', itemIndex); break; case 'getBlockReward': case 'getBlockByNumber': params.blockno = executeFunctions.getNodeParameter('blockNumber', itemIndex); break; case 'getBlockNumberByTime': params.timestamp = executeFunctions.getNodeParameter('timestamp', itemIndex); params.closest = 'before'; break; } // Add pagination parameters for transaction lists if (['getNormalTxs', 'getInternalTxs', 'getTokenTx', 'getTokenNftTx'].includes(operation)) { params.startblock = executeFunctions.getNodeParameter('startBlock', itemIndex, '0'); params.endblock = executeFunctions.getNodeParameter('endBlock', itemIndex, '99999999'); params.page = executeFunctions.getNodeParameter('page', itemIndex, 1); params.offset = executeFunctions.getNodeParameter('offset', itemIndex, 10); params.sort = executeFunctions.getNodeParameter('sort', itemIndex, 'asc'); } // Add tag parameter for balance operations if (['getBalance'].includes(operation)) { params.tag = 'latest'; } } } exports.BlockchainExplorer = BlockchainExplorer;