Nodofi Detailed Handbook
A practical end-to-end guide that shows how to actually run Nodofi in real workflows, with concrete examples and copy-paste commands.
Overview
Nodofi has multiple runtime components. You can start small (Studio + one local Node) and grow into a production network (domain-backed Node, Relay, NVM services, CloudDB, and optional Robot Agent).
Most teams use this sequence:
- Run Studio locally.
- Run one Node and publish a test app.
- Request the app using Nodo JS APIs.
- Add payments (optional).
- Add Relay for reachability without direct inbound networking.
- Add NVM services for headless backend tasks.
- Add CloudDB for shared app/service data.
Architecture map
Studio (build/publish)
-> Node (hosts app files + app API)
-> Relay (optional reachability layer)
-> NVM Service Manager (headless service runtime)
-> CloudDB worker (shared data)
-> MooChedda (USDC settlement + verification)
-> Robot Agent (physical robot runtime, optional)
Key principle: payments settle wallet-to-wallet through MooChedda; infrastructure verifies payments but does not custody funds.
Quick local lab (about 15 minutes)
1. Start Studio
git clone <your repo>
cd BeezifiStudio
npm install
cp .env.example .env
# set DB_USER, DB_PASSWORD, DB_NAME, JWT_SECRET in .env
npm run db:init
npm start
Open http://localhost:3000, create your account, and open the Studio editor.
2. Start a local Node
cd desktop-node
npm install
npm start
Open http://localhost:8800. Copy the Node key from the admin page.
3. Create and publish a minimal app
function NODO_START() {
document.body.innerHTML = 'Hello from Nodofi
My first published app is running.
';
}
In Studio: right click project -> Send to Node. Use http://localhost:8800 and paste the Node key for instant publish.
Publish an app (UI and API)
Studio UI path
- Right click a project -> Send to Node.
- Set Node address (URL or identity-based target).
- Optional: Node key for immediate live publish.
- Optional: list in node directory, icon, screenshots, price.
Equivalent API call
curl -s -X POST https://mainnet.yourdomain.com/api/apps \
-H "Authorization: Bearer <node key>" \
-H "Content-Type: application/json" \
-d '{
"uid": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"name": "Weather Board",
"version": "1.0.0",
"files": [
{"type":"html","name":"index.html","content":"<div id=\"app\"></div>"},
{"type":"js","name":"app.js","content":"function NODO_START(){document.getElementById(\"app\").innerText=\"Online\";}"}
]
}'
Reusing the same uid updates the existing app in place.
Request and run an app from any page
Basic web embedding pattern
<script src="https://mainnet.yourdomain.com/nodo.js"></script>
<div id="mount"></div>
<script>
Nodo.load({
node: 'https://mainnet.yourdomain.com',
uid: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4',
mount: '#mount',
watch: true
});
</script>
When to use watch mode
| Setting | Use when |
|---|---|
watch: true | You are actively iterating in Studio and want open clients to refresh after republish. |
watch: false | You want deterministic behavior without live updates (typical production pages). |
Payments and pricing examples
Set Node pricing policy
curl -s -X POST http://localhost:8800/admin/pricing \
-H "Content-Type: application/json" \
-H "X-Node-Admin: 1" \
-d '{
"wallet": "04...your MooChedda address...",
"commissionRate": 0.15,
"submissionFee": 2
}'
Programmatic MooChedda payment verification
curl -s -X POST https://moochedda.com/transactions/verify \
-H "Content-Type: application/json" \
-d '{
"fromAddress": "...",
"toAddress": "...",
"amount": 2,
"tokenSymbol": "USDC",
"timestamp": 1737111111111,
"signature": "..."
}'
Robust verification pattern:
- Validate signature locally first.
- Verify settlement via MooChedda API.
- Check amount, recipient, timestamp freshness, and replay status.
Relay setup pattern
Use Relay when nodes/services are behind NAT, no public domain, or no router control.
Minimum relay config
RELAY_PUBLIC_URL=https://relay.yourdomain.com
RELAY_NAME=My Relay
RELAY_OPERATOR=Your Org
REGISTRY_URL=https://registry.nodofi.com
# Optional paid access
# ACCESS_FEE_AMOUNT=2
# ACCESS_FEE_WALLET=04...wallet...
# ACCESS_FEE_PERIOD_DAYS=30
Three-step validation
curl -i https://relay.yourdomain.com/
curl -i "https://relay.yourdomain.com/socket.io/?EIO=4&transport=polling"
curl --http1.1 -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
"https://relay.yourdomain.com/socket.io/?EIO=4&transport=websocket"
Expected outcomes: health 200, polling handshake with sid payload, websocket 101.
NVM Service Manager pattern
Service entry template
async function AsyncNodoMain(input, callback) {
const name = input && input.name ? input.name : 'world';
callback({ ok: true, message: 'hello ' + name, at: new Date().toISOString() });
}
Call from another app/service
const out = await NodoRequestAsync({
relay: 'https://relay.nodofi.com',
recp: 'my-service-project-uid',
data: { function: 'main', name: 'Nodofi' }
});
console.log(out);
Operational best practice: issue per-developer API keys in the Manager dashboard instead of sharing one global manager key.
CloudDB pattern
Public table CRUD
const db = new NodoCloudDB({
project: PROJECT_UID,
key: DATA_KEY,
relay: 'https://relay.nodofi.com',
worker: 'NodofiCloudDB'
});
const notes = db.table('notes');
const id = await notes.add({ title: 'first', done: false });
await notes.update(id, { done: true });
const rows = await notes.toArray();
await notes.delete(id);
Private table (wallet-scoped)
const vault = db.table('secrets', {
private: true,
wallet: {
address: MY_MOOCHEDDA_ADDRESS,
privateKey: MY_MOOCHEDDA_PRIVATE_KEY
}
});
await vault.add({ secret: 'wallet-bound row' });
Robot Agent pattern
Minimal robot environment
RELAY_URL=https://relay.nodofi.com
ROBOT_NAME=my-robot-1
HARDWARE=auto
HEARTBEAT_TIMEOUT_MS=3000
Typical first-run flow
- Start robot agent and copy pairing key.
- In Studio Robot project, Add a robot with relay URL + robot name + key.
- Run tethered first, then deploy standalone after hardware validation.
Safety baseline
- Use deploy mode only after confirming emergency STOP behavior.
- For motors/propellers, remove load during first script tests.
- Use isolated external power rails for motor drivers and servos.
Production checklist
| Area | Checklist |
|---|---|
| TLS | HTTPS with valid certificate for all public endpoints (Studio, Node, Relay, Manager admin domains). |
| Proxy | WebSocket upgrade configured for Node and Relay; long read timeout for socket.io. |
| Secrets | Set strong JWT_SECRET; keep key material out of public bundles; use dedicated service users. |
| Backups | Back up DB files/servers and config env files; test restore. |
| Identity | Set stable public addresses and register where needed (Registry, directories). |
| Observability | Enable service stats, keep logs, add uptime checks for health and websocket handshakes. |
Troubleshooting matrix
| Symptom | Likely cause | First fix |
|---|---|---|
| Node cannot connect via relay | WebSocket upgrade blocked by proxy | Re-check proxy websocket config and 101 test. |
| Custom domain verify fails | Resolver lag / negative DNS cache | Validate with public resolver and set DNS_SERVERS override. |
| Published app loads but does not run | No NODO_START in JS | Add entrypoint and republish same UID. |
| CloudDB writes fail | Wrong project key or worker/relay mismatch | Confirm key, relay, worker name, and project UID. |
| NVM publish denied | Wrong API key or revoked key | Generate new developer key in manager dashboard. |
| Robot parts show simulator-only | Missing hardware library | Install required library and restart agent. |
Copy-paste recipes
Recipe A: local sandbox (Studio + Node only)
# terminal 1
cd BeezifiStudio
npm install
npm run db:init
npm start
# terminal 2
cd desktop-node
npm install
npm start
Recipe B: relay-backed topology
Studio (public)
uses relay: https://relay.yourdomain.com
Node (private/home network)
outbound connects to same relay
NVM Manager (private)
outbound connects to same relay
CloudDB worker (private or public)
outbound connects to same relay
Recipe C: pricing-ready node
1) Configure payout wallet in node admin.
2) Set commission rate (0 to 0.5).
3) Optionally set submission fee.
4) In Studio publish dialog, set app price + payout wallet.
5) Verify purchase unlock flow from App Browser.