Skip to content

Commit f07fe3e

Browse files
committed
feat: adopt nano-core defaults and flat nano config
1 parent eb8cb20 commit f07fe3e

25 files changed

Lines changed: 477 additions & 143 deletions

File tree

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ RaiFlow is in the middle of a v2 rebuild.
1111
What is true today:
1212

1313
- The v2 foundation packages exist and build: `config`, `storage`, `events`, `rpc`, `custody`
14-
- The daemon boots from `raiflow.yaml`
14+
- The daemon boots from `raiflow.yml`
1515
- SQLite migrations run on startup
1616
- The event store and event bus are implemented
1717
- The RPC package has multi-node client/failover primitives
@@ -128,10 +128,14 @@ pnpm install
128128
2. Create a config file:
129129

130130
```bash
131-
cp raiflow.yaml.example raiflow.yaml
131+
cp raiflow.yml.example raiflow.yml
132132
```
133133

134-
3. Fill in the required environment variables referenced by `raiflow.yaml`
134+
3. Fill in any environment variables referenced by the features you enable in `raiflow.yml`
135+
136+
For the default example, none are required just to boot locally. `NANO_RPC_URL`,
137+
`NANO_WS_URL`, and `NANO_WORK_URL` are optional endpoint overrides. `RAIFLOW_SEED` and
138+
`RAIFLOW_REPRESENTATIVE` are only needed when you enable custody-backed features.
135139

136140
4. Build the workspace:
137141

apps/site/docs/runtime/index.md

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This page describes the runtime as it exists today, not only as it is intended t
66

77
The runtime currently does these things reliably:
88

9-
- boots from `raiflow.yaml`
9+
- boots from `raiflow.yml`
1010
- opens SQLite storage and runs migrations
1111
- wires the event store and event bus
1212
- exposes a small HTTP surface inherited from the earlier invoice prototype
@@ -66,32 +66,39 @@ Do not assume the current codebase has complete production-grade auth behavior w
6666

6767
## Configuration
6868

69-
Runtime startup uses `raiflow.yaml`.
69+
Runtime startup uses `raiflow.yml`.
7070

7171
Example shape:
7272

7373
```yaml
7474
daemon:
7575
host: "0.0.0.0"
7676
port: 3100
77-
apiKey: "env:RAIFLOW_API_KEY"
77+
# apiKey: "env:RAIFLOW_API_KEY"
7878

7979
nano:
80-
nodes:
81-
- rpc: "env:NANO_RPC_URL"
82-
ws: "env:NANO_WS_URL"
83-
priority: 1
80+
rpc: []
81+
ws: []
82+
work: []
83+
# rpc: ["env:NANO_RPC_URL"]
84+
# ws: ["env:NANO_WS_URL"]
85+
# work: ["env:NANO_WORK_URL"]
8486

85-
custody:
86-
seed: "env:RAIFLOW_SEED"
87-
representative: "env:RAIFLOW_REPRESENTATIVE"
87+
# custody:
88+
# seed: "env:RAIFLOW_SEED"
89+
# representative: "env:RAIFLOW_REPRESENTATIVE"
8890

8991
storage:
9092
driver: "sqlite"
9193
path: "./raiflow.db"
9294
```
9395
94-
See the repository `raiflow.yaml.example` for the full current example.
96+
With `@openrai/nano-core` v2, `NANO_RPC_URL`, `NANO_WS_URL`, and `NANO_WORK_URL`
97+
are best treated as optional endpoint overrides rather than mandatory startup
98+
variables. A custody `representative` is still required if you enable the
99+
`custody` block.
100+
101+
See the repository `raiflow.yml.example` for the full current example.
95102

96103
## Read With Care
97104

docs/architectural-review.md

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,20 +227,16 @@ Common error codes:
227227
## Configuration Shape
228228

229229
```yaml
230-
# raiflow.yaml
230+
# raiflow.yml
231231
daemon:
232232
host: "127.0.0.1"
233233
port: 7400
234234
apiKey: "env:RAIFLOW_API_KEY"
235235

236236
nano:
237-
nodes:
238-
- rpc: "http://localhost:7076"
239-
ws: "ws://localhost:7078"
240-
priority: 1
241-
- rpc: "http://backup:7076"
242-
ws: "ws://backup:7078"
243-
priority: 2
237+
rpc: ["http://localhost:7076", "http://backup:7076"]
238+
ws: ["ws://localhost:7078", "ws://backup:7078"]
239+
work: []
244240

245241
custody:
246242
seed: "env:RAIFLOW_SEED"
@@ -272,7 +268,7 @@ logging:
272268
Each milestone is complete when:
273269
274270
**M1 (Foundation)**
275-
- `raiflow` starts from `raiflow.yaml`
271+
- `raiflow` starts from `raiflow.yml`
276272
- Migrations run automatically
277273
- Auth rejects unauthenticated requests
278274
- `GET /health` returns `{"status":"ok"}`

docs/progress.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ Building in order:
6464

6565
Current frontier:
6666
- RaiFlow `packages/rpc` now consumes the local `@openrai/nano-core` transport pools instead of maintaining its own HTTP/WebSocket transport primitives.
67-
- The workspace is temporarily linked to the sibling `../nano-core` checkout so transport/auth work can land and be validated end-to-end before publish.
6867
- RaiFlow `packages/watcher` RPC polling and WebSocket observation now also consume the local `@openrai/nano-core` transport pools.
6968
- `nano-core` defaults now reflect the April 2026 endpoint policy: four default RPC endpoints, `wss://rpc.nano.to` for WS, and `https://rpc.nano.to` as the only default public work endpoint.
7069
- `packages/rpc` now derives `connected` and `failover` state changes from the shared transport foundation rather than maintaining a disconnected placeholder view of active node state.

examples/htmx-wallet/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
"dependencies": {
1111
"express": "^4.19.0",
1212
"@openrai/raiflow-sdk": "workspace:*",
13-
"@openrai/nano-core": "link:../../../nano-core"
13+
"@openrai/nano-core": "2.1.0"
1414
}
1515
}

examples/next-checkout/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@
1313
"react": "^18.3.0",
1414
"react-dom": "^18.3.0",
1515
"@openrai/raiflow-sdk": "workspace:*",
16-
"@openrai/nano-core": "link:../../../nano-core"
16+
"@openrai/nano-core": "2.1.0"
1717
}
1818
}

packages/config/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
},
1515
"scripts": {
1616
"build": "tsc",
17-
"test": "echo \"No tests yet\"",
17+
"test": "vitest run",
1818
"lint": "tsc --noEmit"
1919
},
2020
"dependencies": {
2121
"yaml": "^2.8.3"
2222
},
2323
"devDependencies": {
2424
"@types/node": "^25.5.0",
25-
"typescript": "^5.8.2"
25+
"typescript": "^5.8.2",
26+
"vitest": "^2.1.9"
2627
}
2728
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { afterEach, describe, expect, it } from 'vitest';
2+
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
3+
import { tmpdir } from 'node:os';
4+
import { join } from 'node:path';
5+
import { loadConfig } from '../index.js';
6+
7+
function writeConfig(contents: string): string {
8+
const dir = mkdtempSync(join(tmpdir(), 'raiflow-config-'));
9+
const path = join(dir, 'raiflow.yml');
10+
writeFileSync(path, contents, 'utf8');
11+
return path;
12+
}
13+
14+
const tempPaths: string[] = [];
15+
16+
afterEach(() => {
17+
for (const path of tempPaths.splice(0)) {
18+
rmSync(path, { recursive: true, force: true });
19+
}
20+
});
21+
22+
describe('loadConfig nano transport arrays', () => {
23+
it('accepts an empty nano block', () => {
24+
const path = writeConfig('nano: {}\n');
25+
tempPaths.push(path.replace(/\/raiflow\.yml$/, ''));
26+
27+
const config = loadConfig(path);
28+
expect(config.nano).toEqual({ rpc: [], ws: [], work: [] });
29+
});
30+
31+
it('accepts flat rpc override list', () => {
32+
const path = writeConfig('nano:\n rpc: ["https://rpc.example.com"]\n');
33+
tempPaths.push(path.replace(/\/raiflow\.yml$/, ''));
34+
35+
const config = loadConfig(path);
36+
expect(config.nano).toEqual({ rpc: ['https://rpc.example.com'], ws: [], work: [] });
37+
});
38+
39+
it('accepts flat rpc, ws, and work override lists', () => {
40+
const path = writeConfig('nano:\n rpc: ["https://rpc.example.com"]\n ws: ["wss://ws.example.com"]\n work: ["https://work.example.com"]\n');
41+
tempPaths.push(path.replace(/\/raiflow\.yml$/, ''));
42+
43+
const config = loadConfig(path);
44+
expect(config.nano).toEqual({ rpc: ['https://rpc.example.com'], ws: ['wss://ws.example.com'], work: ['https://work.example.com'] });
45+
});
46+
});

packages/config/src/index.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,10 @@ export interface DaemonConfig {
99
apiKey?: string;
1010
}
1111

12-
export interface NanoNodeConfig {
13-
rpc: string;
14-
ws: string;
15-
priority: number;
16-
}
17-
1812
export interface NanoConfig {
19-
nodes: NanoNodeConfig[];
13+
rpc: string[];
14+
ws: string[];
15+
work: string[];
2016
}
2117

2218
export interface CustodyConfig {
@@ -168,16 +164,19 @@ function parseDaemon(obj: Record<string, unknown>): DaemonConfig {
168164

169165
function parseNano(obj: Record<string, unknown>): NanoConfig {
170166
const nano = isObject(obj.nano) ? obj.nano : {};
171-
const nodes = Array.isArray(nano.nodes) ? nano.nodes : [];
167+
const rpc = Array.isArray(nano.rpc)
168+
? (resolveEnvValue(nano.rpc) as unknown[]).filter(isString)
169+
: [];
170+
const ws = Array.isArray(nano.ws)
171+
? (resolveEnvValue(nano.ws) as unknown[]).filter(isString)
172+
: [];
173+
const work = Array.isArray(nano.work)
174+
? (resolveEnvValue(nano.work) as unknown[]).filter(isString)
175+
: [];
172176
return {
173-
nodes: nodes.map((n, i) => {
174-
if (!isObject(n)) throw new Error(`config.nano.nodes[${i}] must be an object`);
175-
return {
176-
rpc: resolveEnv(requireString(n as Record<string, unknown>, 'rpc')),
177-
ws: resolveEnv(requireString(n as Record<string, unknown>, 'ws')),
178-
priority: requireNumber(n as Record<string, unknown>, 'priority'),
179-
};
180-
}),
177+
rpc,
178+
ws,
179+
work,
181180
};
182181
}
183182

packages/custody/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
},
2020
"dependencies": {
2121
"@openrai/model": "workspace:*",
22-
"@openrai/nano-core": "link:../../../nano-core",
22+
"@openrai/nano-core": "2.1.0",
2323
"nanocurrency": "^2.5.0"
2424
},
2525
"devDependencies": {

0 commit comments

Comments
 (0)