@cryptodevops/n8n-nodes-blockstream-api
Version:
n8n node for Blockstream API (Esplora) - Bitcoin transactions, mempool, UTXO
287 lines (286 loc) • 13.1 kB
JavaScript
;
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;