UNPKG

@cryptodevops/n8n-nodes-blockstream-api

Version:

n8n node for Blockstream API (Esplora) - Bitcoin transactions, mempool, UTXO

287 lines (286 loc) 13.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.BlockstreamApi = void 0; const n8n_workflow_1 = require("n8n-workflow"); const axios_1 = __importDefault(require("axios")); class BlockstreamApi { constructor() { this.description = { displayName: 'Blockstream API (Esplora)', name: 'blockstreamApi', icon: 'file:nodes/BlockstreamApi/blockstream.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"]}}', description: 'Accède aux données Bitcoin via l\'API Blockstream (Esplora) - Transactions, mempool, UTXO', defaults: { name: 'Blockstream API', }, inputs: ["main" /* NodeConnectionType.Main */], outputs: ["main" /* NodeConnectionType.Main */], properties: [ { displayName: 'Network', name: 'network', type: 'options', noDataExpression: true, options: [ { name: 'Bitcoin Mainnet', value: 'mainnet', description: 'Réseau Bitcoin principal', }, { name: 'Bitcoin Testnet', value: 'testnet', description: 'Réseau de test Bitcoin', }, { name: 'Liquid', value: 'liquid', description: 'Réseau Liquid', }, { name: 'Liquid Testnet', value: 'liquidtestnet', description: 'Réseau de test Liquid', }, ], default: 'mainnet', description: 'Réseau Bitcoin à utiliser', }, { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, options: [ { name: 'Get Transaction', value: 'getTransaction', description: 'Récupère les informations d\'une transaction', action: 'Get transaction information', }, { name: 'Get Transaction Status', value: 'getTransactionStatus', description: 'Récupère le statut de confirmation d\'une transaction', action: 'Get transaction status', }, { name: 'Get Address Info', value: 'getAddressInfo', description: 'Récupère les informations d\'une adresse', action: 'Get address information', }, { name: 'Get Address Transactions', value: 'getAddressTransactions', description: 'Récupère l\'historique des transactions d\'une adresse', action: 'Get address transactions', }, { name: 'Get Address UTXO', value: 'getAddressUtxo', description: 'Récupère les UTXO d\'une adresse', action: 'Get address UTXO', }, { name: 'Get Block Info', value: 'getBlockInfo', description: 'Récupère les informations d\'un bloc', action: 'Get block information', }, { name: 'Get Latest Blocks', value: 'getLatestBlocks', description: 'Récupère les derniers blocs', action: 'Get latest blocks', }, { name: 'Get Mempool Stats', value: 'getMempoolStats', description: 'Récupère les statistiques du mempool', action: 'Get mempool statistics', }, { name: 'Broadcast Transaction', value: 'broadcastTransaction', description: 'Diffuse une transaction sur le réseau', action: 'Broadcast transaction', }, ], default: 'getTransaction', }, { displayName: 'Transaction ID', name: 'txid', type: 'string', displayOptions: { show: { operation: ['getTransaction', 'getTransactionStatus'], }, }, default: '', placeholder: 'f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16', description: 'ID de la transaction à récupérer', required: true, }, { displayName: 'Address', name: 'address', type: 'string', displayOptions: { show: { operation: ['getAddressInfo', 'getAddressTransactions', 'getAddressUtxo'], }, }, default: '', placeholder: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', description: 'Adresse Bitcoin à analyser', required: true, }, { displayName: 'Block Hash', name: 'blockHash', type: 'string', displayOptions: { show: { operation: ['getBlockInfo'], }, }, default: '', placeholder: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f', description: 'Hash du bloc à récupérer', required: true, }, { displayName: 'Raw Transaction (Hex)', name: 'rawTransaction', type: 'string', displayOptions: { show: { operation: ['broadcastTransaction'], }, }, default: '', description: 'Transaction brute en format hexadécimal', required: true, }, { displayName: 'Limit', name: 'limit', type: 'number', displayOptions: { show: { operation: ['getAddressTransactions'], }, }, default: 25, description: 'Nombre maximum de transactions à retourner', typeOptions: { minValue: 1, maxValue: 50, }, }, ], }; } async execute() { const items = this.getInputData(); const returnData = []; for (let i = 0; i < items.length; i++) { try { const operation = this.getNodeParameter('operation', i); const network = this.getNodeParameter('network', i); // Build base URL based on network let baseUrl = 'https://blockstream.info/api/'; switch (network) { case 'testnet': baseUrl = 'https://blockstream.info/testnet/api/'; break; case 'liquid': baseUrl = 'https://blockstream.info/liquid/api/'; break; case 'liquidtestnet': baseUrl = 'https://blockstream.info/liquidtestnet/api/'; break; default: baseUrl = 'https://blockstream.info/api/'; } let responseData; switch (operation) { case 'getTransaction': const txid = this.getNodeParameter('txid', i); const txResponse = await axios_1.default.get(`${baseUrl}tx/${txid}`); responseData = txResponse.data; break; case 'getTransactionStatus': const statusTxid = this.getNodeParameter('txid', i); const statusResponse = await axios_1.default.get(`${baseUrl}tx/${statusTxid}/status`); responseData = statusResponse.data; break; case 'getAddressInfo': const address = this.getNodeParameter('address', i); const addressResponse = await axios_1.default.get(`${baseUrl}address/${address}`); responseData = addressResponse.data; break; case 'getAddressTransactions': const txAddress = this.getNodeParameter('address', i); const limit = this.getNodeParameter('limit', i); const txsResponse = await axios_1.default.get(`${baseUrl}address/${txAddress}/txs`); responseData = limit ? txsResponse.data.slice(0, limit) : txsResponse.data; break; case 'getAddressUtxo': const utxoAddress = this.getNodeParameter('address', i); const utxoResponse = await axios_1.default.get(`${baseUrl}address/${utxoAddress}/utxo`); responseData = utxoResponse.data; break; case 'getBlockInfo': const blockHash = this.getNodeParameter('blockHash', i); const blockResponse = await axios_1.default.get(`${baseUrl}block/${blockHash}`); responseData = blockResponse.data; break; case 'getLatestBlocks': const blocksResponse = await axios_1.default.get(`${baseUrl}blocks`); responseData = blocksResponse.data; break; case 'getMempoolStats': const mempoolResponse = await axios_1.default.get(`${baseUrl}mempool`); responseData = mempoolResponse.data; break; case 'broadcastTransaction': const rawTx = this.getNodeParameter('rawTransaction', i); const broadcastResponse = await axios_1.default.post(`${baseUrl}tx`, rawTx, { headers: { 'Content-Type': 'text/plain', }, }); responseData = { txid: broadcastResponse.data }; break; default: throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Opération non supportée: ${operation}`, { itemIndex: i }); } returnData.push({ json: responseData, pairedItem: { item: i }, }); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message }, pairedItem: { item: i }, }); continue; } throw new n8n_workflow_1.NodeOperationError(this.getNode(), error, { itemIndex: i }); } } return [returnData]; } } exports.BlockstreamApi = BlockstreamApi;