The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Orquestador Multichain AcademicChain",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "emitir-multichain",
"options": {}
},
"name": "Webhook_Entrada",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
0,
0
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.headers['x-acl-auth-key']}}",
"operation": "equal",
"value2": "={{$env.ACL_AUTH_KEY}}"
}
]
}
},
"name": "Auth_Check",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
200,
0
]
},
{
"parameters": {
"respondWith": "json",
"responseBody": "{\"error\": \"Unauthorized\"}",
"options": {
"responseCode": 401
}
},
"name": "Reject",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
200,
200
]
},
{
"parameters": {
"jsCode": "const q = $json.query || {}; const b = $json.body || {}; const docHash = String(q.documentHash || b.documentHash || b.uniqueHash || '').trim(); const studentName = String(q.studentName || b.studentName || '').trim(); const pdfUrl = String(q.pdfUrl || b.pdfUrl || '').trim(); const pdfBase64 = String(q.pdfBase64 || b.pdfBase64 || '').trim(); let plan = String(q.plan || b.plan || '').toLowerCase().trim(); const uniqueHash = docHash || ('hash-'+Date.now()); const normalizePlan = (p)=>{ if(['triple','3','enterprise','ent','empresarial'].includes(p)) return 'triple'; if(['dual','2','professional','pro','profesional'].includes(p)) return 'dual'; if(['base','1','basic','esencial','essential'].includes(p)) return 'base'; return 'base'; }; const planNormalized = normalizePlan(plan); return { json: { uniqueHash, studentName, plan: planNormalized, originalPlan: plan || 'auto', pdfUrl, pdfBase64 } };"
},
"name": "Normalize Input",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
400,
0
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.plan}}",
"operation": "equal",
"value2": "triple"
}
]
}
},
"name": "Is Triple",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
600,
-120
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.plan}}",
"operation": "equal",
"value2": "dual"
}
]
}
},
"name": "Is Dual",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
600,
120
]
},
{
"parameters": {
"jsCode": "const tx = '0.0.' + (Math.floor(Math.random()*9000000)+1000000) + '@' + Date.now(); return { json: { ...$json, hederaTx: tx } };"
},
"name": "Hedera Issue",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
820,
-200
]
},
{
"parameters": {
"jsCode": "const x = 'xrpl-' + Math.random().toString(16).slice(2) + '-' + Date.now(); return { json: { ...$json, xrpTxHash: x } };"
},
"name": "XRP_Emit",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
820,
0
]
},
{
"parameters": {
"jsCode": "const a = 'algo-' + Math.random().toString(16).slice(2) + '-' + Date.now(); return { json: { ...$json, algoTxId: a } };"
},
"name": "Algorand_Emit",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
820,
200
]
},
{
"parameters": {
"mode": "combine",
"combination": "mergeByPosition"
},
"name": "Unir_Hashes",
"type": "n8n-nodes-base.merge",
"typeVersion": 1,
"position": [
1040,
0
]
},
{
"parameters": {
"jsCode": "const items = $items(); let h=null,x=null,a=null,base=null; for (const it of items) { const j = it.json||{}; if (j.hederaTx) h=j.hederaTx; if (j.xrpTxHash) x=j.xrpTxHash; if (j.algoTxId) a=j.algoTxId; if (j.uniqueHash && !base) base=j; } const out = { uniqueHash: base?.uniqueHash || $json.uniqueHash, studentName: base?.studentName || $json.studentName, externalProofs: {} }; if (h) out.externalProofs.hederaTx = h; if (x) out.externalProofs.xrpTxHash = x; if (a) out.externalProofs.algoTxId = a; out.hash_hedera = h || null; out.hash_xrp = x || null; out.hash_algo = a || null; const tokenId = (h && h.includes('@')) ? h.split('@')[0] : ('0.0.' + (Math.floor(Math.random()*9000000)+1000000)); out.tokenId = tokenId; out.serialNumber = '1'; out.universityId = null; out.studentAccountId = null; out.updatedAt = new Date().toISOString(); if (!out.createdAt) out.createdAt = out.updatedAt; return { json: out };"
},
"name": "Consolidate Proofs",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1240,
0
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.pdfUrl}}",
"operation": "isNotEmpty"
}
]
}
},
"name": "Has PDF",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1320,
0
]
},
{
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$json.pdfBase64}}",
"operation": "isNotEmpty"
}
]
}
},
"name": "Has Base64",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1320,
120
]
},
{
"parameters": {
"url": "={{$json.pdfUrl}}",
"method": "GET",
"download": true
},
"name": "Fetch PDF",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1400,
-120
]
},
{
"parameters": {
"jsCode": "const b64 = String($json.pdfBase64 || '').trim(); const clean = b64.includes(',') ? b64.split(',').pop() : b64; if (!clean) { return { json: $json }; } const buf = Buffer.from(clean, 'base64'); return { json: $json, binary: { file: { data: buf, mimeType: 'application/pdf', fileName: 'credential.pdf' } } };"
},
"name": "Create Binary (Base64)",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1440,
120
]
},
{
"parameters": {
"mode": "move",
"options": {
"setAll": true
},
"sourceKey": "data",
"destinationKey": "file"
},
"name": "Prepare Binary",
"type": "n8n-nodes-base.moveBinaryData",
"typeVersion": 1,
"position": [
1500,
-120
]
},
{
"parameters": {
"url": "https://node.lighthouse.storage/api/v0/add",
"method": "POST",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "={{'Bearer ' + $env.FILECOIN_API_KEY}}"
}
]
},
"sendFormData": true,
"formDataParametersUi": {
"parameter": [
{
"name": "file",
"value": "={{$binary.file}}",
"type": "formBinary"
}
]
}
},
"name": "Upload File (Filecoin)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1600,
-120
]
},
{
"parameters": {
"jsCode": "const doc = { tokenId: $json.tokenId, serialNumber: $json.serialNumber || '1', universityId: $json.universityId || null, studentAccountId: $json.studentAccountId || null, uniqueHash: $json.uniqueHash, studentName: $json.studentName || null, externalProofs: $json.externalProofs || {}, createdAt: $json.createdAt || new Date().toISOString(), updatedAt: $json.updatedAt || new Date().toISOString() }; const jsonString = JSON.stringify(doc); const buf = Buffer.from(jsonString); return { json: doc, binary: { file: { data: buf.toString('base64'), mimeType: 'application/json', fileName: 'metadata.json' } } };"
},
"name": "Build Doc JSON",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1360,
0
]
},
{
"parameters": {
"url": "https://node.lighthouse.storage/api/v0/add",
"method": "POST",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "={{'Bearer ' + $env.FILECOIN_API_KEY}}"
}
]
},
"sendFormData": true,
"formDataParametersUi": {
"parameter": [
{
"name": "file",
"value": "={{$binary.file}}",
"type": "formBinary"
}
]
}
},
"name": "Upload JSON (Filecoin)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1500,
0
]
},
{
"parameters": {
"jsCode": "let shaVal = null; const resp = $input.item.json || {}; const ipfsHash = resp.IpfsHash || resp.ipfsHash || resp.Hash || null; const ipfsURI = ipfsHash ? ('ipfs://' + ipfsHash) : null; const link = ipfsURI || (resp.pinata_url || null); const toHash = String(link || '').trim(); try { const crypto = require('crypto'); if (toHash) { shaVal = 'hash-' + crypto.createHash('sha256').update(toHash).digest('hex'); } } catch (e) { if (toHash) { let h = 0; for (let i = 0; i < toHash.length; i++) { h = ((h << 5) - h) + toHash.charCodeAt(i); h |= 0; } shaVal = 'hash-fallback-' + Math.abs(h).toString(16); } } const out = { ...$json, ipfsURI: ipfsURI || $json.ipfsURI || null, uniqueHash: shaVal || $json.uniqueHash, updatedAt: new Date().toISOString() }; return { json: out };"
},
"name": "Compute SHA256 Link",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1700,
-40
]
},
{
"parameters": {
"url": "={{$env.API_URL || 'https://academicchain-ledger.onrender.com'}}/api/v1/credentials/issue-unified",
"method": "POST",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "X-API-Key",
"value": "={{$env.ACADEMIC_CHAIN_API_KEY || ''}}"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={ \"tokenId\": \"{{$json.tokenId}}\", \"uniqueHash\": \"{{$json.uniqueHash}}\", \"ipfsURI\": \"{{$json.ipfsURI}}\", \"studentName\": \"{{$json.studentName || ''}}\", \"degree\": \"{{$json.degree || $json.title || ''}}\", \"recipientAccountId\": \"{{$json.studentAccountId || ''}}\", \"plan\": \"{{$json.plan || 'base'}}\" }",
"options": {}
},
"name": "Issue Unified (Backend)",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
1880,
80
]
},
{
"parameters": {
"operation": "update",
"collection": "credentials",
"query": "={\"uniqueHash\": {{$json.uniqueHash}} }",
"fieldsUi": {
"field": [
{
"fieldName": "uniqueHash",
"fieldValue": "={{$json.uniqueHash}}"
},
{
"fieldName": "studentName",
"fieldValue": "={{$json.studentName}}"
},
{
"fieldName": "externalProofs",
"fieldValue": "={{$json.externalProofs}}"
},
{
"fieldName": "externalProofs.xrpTxHash",
"fieldValue": "={{$json.hash_xrp}}"
},
{
"fieldName": "externalProofs.hederaTx",
"fieldValue": "={{$json.hash_hedera}}"
},
{
"fieldName": "externalProofs.algoTxId",
"fieldValue": "={{$json.hash_algo}}"
},
{
"fieldName": "ipfsURI",
"fieldValue": "={{$json.ipfsURI}}"
},
{
"fieldName": "tokenId",
"fieldValue": "={{$json.tokenId}}"
},
{
"fieldName": "serialNumber",
"fieldValue": "={{$json.serialNumber || '1'}}"
},
{
"fieldName": "universityId",
"fieldValue": "={{$json.universityId}}"
},
{
"fieldName": "studentAccountId",
"fieldValue": "={{$json.studentAccountId}}"
},
{
"fieldName": "createdAt",
"fieldValue": "={{$json.createdAt}}"
},
{
"fieldName": "updatedAt",
"fieldValue": "={{$json.updatedAt}}"
}
]
},
"options": {
"upsert": true
}
},
"name": "Guardar_MongoDB_MultiChain",
"type": "n8n-nodes-base.mongoDb",
"typeVersion": 1,
"position": [
1860,
-40
],
"credentials": {
"mongoDb": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"respondWith": "json",
"responseBody": "{ \"success\": true, \"data\": {{$json}} }",
"options": {}
},
"name": "Respond",
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1,
"position": [
2060,
-40
]
}
],
"connections": {
"Webhook_Entrada": {
"main": [
[
{
"node": "Auth_Check",
"type": "main",
"index": 0
}
]
]
},
"Auth_Check": {
"main": [
[
{
"node": "Normalize Input",
"type": "main",
"index": 0
}
],
[
{
"node": "Reject",
"type": "main",
"index": 0
}
]
]
},
"Normalize Input": {
"main": [
[
{
"node": "Is Triple",
"type": "main",
"index": 0
}
]
]
},
"Is Triple": {
"main": [
[
{
"node": "Hedera Issue",
"type": "main",
"index": 0
},
{
"node": "XRP_Emit",
"type": "main",
"index": 0
},
{
"node": "Algorand_Emit",
"type": "main",
"index": 0
}
],
[
{
"node": "Is Dual",
"type": "main",
"index": 0
}
]
]
},
"Is Dual": {
"main": [
[
{
"node": "Hedera Issue",
"type": "main",
"index": 0
},
{
"node": "XRP_Emit",
"type": "main",
"index": 0
}
],
[
{
"node": "Hedera Issue",
"type": "main",
"index": 0
}
]
]
},
"Hedera Issue": {
"main": [
[
{
"node": "Unir_Hashes",
"type": "main",
"index": 0
}
]
]
},
"XRP_Emit": {
"main": [
[
{
"node": "Unir_Hashes",
"type": "main",
"index": 1
}
]
]
},
"Algorand_Emit": {
"main": [
[
{
"node": "Unir_Hashes",
"type": "main",
"index": 2
}
]
]
},
"Unir_Hashes": {
"main": [
[
{
"node": "Consolidate Proofs",
"type": "main",
"index": 0
}
]
]
},
"Consolidate Proofs": {
"main": [
[
{
"node": "Has PDF",
"type": "main",
"index": 0
}
]
]
},
"Has PDF": {
"main": [
[
{
"node": "Fetch PDF",
"type": "main",
"index": 0
}
],
[
{
"node": "Has Base64",
"type": "main",
"index": 0
}
]
]
},
"Has Base64": {
"main": [
[
{
"node": "Create Binary (Base64)",
"type": "main",
"index": 0
}
],
[
{
"node": "Build Doc JSON",
"type": "main",
"index": 0
}
]
]
},
"Fetch PDF": {
"main": [
[
{
"node": "Prepare Binary",
"type": "main",
"index": 0
}
]
]
},
"Prepare Binary": {
"main": [
[
{
"node": "Upload File (Filecoin)",
"type": "main",
"index": 0
}
]
]
},
"Create Binary (Base64)": {
"main": [
[
{
"node": "Upload File (Filecoin)",
"type": "main",
"index": 0
}
]
]
},
"Upload File (Filecoin)": {
"main": [
[
{
"node": "Compute SHA256 Link",
"type": "main",
"index": 0
}
]
]
},
"Build Doc JSON": {
"main": [
[
{
"node": "Upload JSON (Filecoin)",
"type": "main",
"index": 0
}
]
]
},
"Upload JSON (Filecoin)": {
"main": [
[
{
"node": "Compute SHA256 Link",
"type": "main",
"index": 0
}
]
]
},
"Compute SHA256 Link": {
"main": [
[
{
"node": "Guardar_MongoDB_MultiChain",
"type": "main",
"index": 0
},
{
"node": "Issue Unified (Backend)",
"type": "main",
"index": 0
}
]
]
},
"Guardar_MongoDB_MultiChain": {
"main": [
[
{
"node": "Respond",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
mongoDb
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Orquestador Multichain AcademicChain. Uses httpRequest, moveBinaryData, mongoDb. Webhook trigger; 23 nodes.
Source: https://github.com/Aether-Connect-Labs/AcademicChain-Ledger/blob/main/n8n/workflows/multichain-orchestrator.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow demonstrates how to export SQL to XML and present the data nicely formatted using an XSL Template.
CyberShield Universal Workflow v4. Uses mongoDb, ssh, httpRequest. Webhook trigger; 7 nodes.
UFRO PP3 Orchestrator Workflow. Uses httpRequest, mongoDb. Webhook trigger; 7 nodes.
CyberShield — Attack Executor. Uses mongoDb, ssh, httpRequest. Webhook trigger; 6 nodes.
CyberShield — Attack Executor. Uses mongoDb, ssh, httpRequest. Webhook trigger; 6 nodes.