Nodofi Docs

Running Nodofi UtilityServices

A small Node.js relay worker for reusable utilities. Run it on your own computer or server, keep it behind your relay, and call it from Studio Flows or any application.

Overview

UtilityServices joins a Nodofi relay under a name such as UtilityServices. It does not need an inbound port or a public domain. A Flow sends a request to that worker and receives one response.

It includes QR code generation, JSON conversion, Base64, hashing, UUIDs, random tokens, time, templates, and optional local Ollama prompts.

Download UtilityServices

Install & run

Download the package, extract it, and run:

sh

Set the relay and worker name in .env:

env

The Ollama settings are optional. UtilityServices starts without Ollama installed.

Functions

Send a request with NodoRequestAsync. The response has result: true when the operation succeeds.

js
  • qr returns a PNG data URL from text.
  • json.parse and json.stringify convert JSON values.
  • base64.encode and base64.decode convert text.
  • hash accepts algorithms such as sha256 and sha512.
  • uuid, random, time, and template provide common application utilities.
  • ollama, ollama.generate, and ollama.embedding use the local Ollama API when enabled.

Using it from Flows

Add a Call relay worker block and set:

text

Build a request object before the block:

js

Connect the request to the block's data input. Its reply output contains the UtilityServices response and can be connected to a Service Output or another Code block.

Optional Ollama

Install Ollama separately, start it, and download a model:

sh
js

Security

Set a long random UTILITY_AUTH_SECRET in the worker's .env to require HMAC-SHA256 signed requests. The signature covers the timestamp, a unique nonce, and the request payload. Stale timestamps and reused nonces are rejected to limit replay attacks.

UTILITY_AUTH_SECRET=replace-with-a-long-random-secret
ALLOWED_SENDERS=your-flow-or-backend-name
AUTH_MAX_AGE_SECONDS=300
MAX_REQUEST_BYTES=262144
RATE_LIMIT_PER_MINUTE=60
const crypto = require('node:crypto');
const payload = { function: 'qr', text: 'https://example.com' };
const timestamp = Math.floor(Date.now() / 1000);
const nonce = crypto.randomBytes(16).toString('hex');
const signature = crypto.createHmac('sha256', process.env.UTILITY_AUTH_SECRET)
  .update(`${timestamp}.${nonce}.${JSON.stringify(payload)}`)
  .digest('hex');

const reply = await NodoRequestAsync('UtilityServices', {
  ...payload,
  auth: { timestamp, nonce, signature }
}, 'https://relay.nodofi.com');

Keep the secret in a trusted backend or service runtime. Never put it in public browser JavaScript. For browser-facing apps, call your own authenticated backend, which signs the request and forwards it to UtilityServices.

ALLOWED_SENDERS restricts relay sender identities. The worker also enforces request-size and per-sender rate limits. Use a private relay for stronger isolation and do not send passwords, API keys, or private prompts through an unprotected worker.

Deposit credits instead of paying per request

For high-volume services, set MOOCHEDDA_WALLET and CREDIT_COST_USDC. The owner controls the price per transaction, while the user can choose how many transactions to buy. One deposit funds the account, and UtilityServices debits it locally for each operation. No new blockchain transaction is created for every request.

MOOCHEDDA_API=https://moochedda.com
MOOCHEDDA_WALLET=04...
CREDIT_COST_USDC=0.01
PAYMENT_MAX_AGE_SECONDS=1800
CREDIT_LEDGER_FILE=.credit-ledger.json
DEPOSIT_OPTIONS_USDC=25,50,100,500
ALLOW_CUSTOM_DEPOSITS=true
MIN_CUSTOM_DEPOSIT_USDC=1
MAX_CUSTOM_DEPOSIT_USDC=10000
const accountKey = crypto.randomBytes(32).toString('hex');
const quote = await NodoRequestAsync('UtilityServices', {
  function: 'account.deposit.quote', transactions: 1000
}, 'https://relay.nodofi.com');

const deposit = await NodoRequestAsync('UtilityServices', {
  function: 'account.deposit', accountKey, transactions: quote.transactions,
  payment: signedSettledTransfer // must equal quote.amount USDC
}, 'https://relay.nodofi.com');

const balance = await NodoRequestAsync('UtilityServices', {
  function: 'account.balance', account: deposit.account, accountKey
}, 'https://relay.nodofi.com');

const reply = await NodoRequestAsync('UtilityServices', {
  function: 'qr', text: 'https://example.com', account: deposit.account, accountKey
}, 'https://relay.nodofi.com');

account.deposit.quote calculates the exact USDC amount for a requested transaction count. account.deposit.options returns the configured lots. account.balance returns deposited, spent, remaining USDC, and remaining transactions. The worker verifies the deposit's recipient, USDC token, timestamp, settlement, and one-time payment signature. Keep .credit-ledger.json private and backed up.

Keep OLLAMA_HOST bound to localhost unless you intentionally protect the remote Ollama endpoint. UtilityServices does not expose Ollama directly; it only makes local requests on the machine where it runs.