@ottocode/server 0.1.243 → 0.1.245

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ottocode/server",
3
- "version": "0.1.243",
3
+ "version": "0.1.245",
4
4
  "description": "HTTP API server for ottocode",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -49,8 +49,8 @@
49
49
  "typecheck": "tsc --noEmit"
50
50
  },
51
51
  "dependencies": {
52
- "@ottocode/sdk": "0.1.243",
53
- "@ottocode/database": "0.1.243",
52
+ "@ottocode/sdk": "0.1.245",
53
+ "@ottocode/database": "0.1.245",
54
54
  "drizzle-orm": "^0.44.5",
55
55
  "hono": "^4.9.9",
56
56
  "zod": "^4.3.6"
@@ -2,15 +2,15 @@ export type OttoEventType =
2
2
  | 'tool.approval.required'
3
3
  | 'tool.approval.updated'
4
4
  | 'tool.approval.resolved'
5
- | 'setu.payment.required'
6
- | 'setu.payment.signing'
7
- | 'setu.payment.complete'
8
- | 'setu.payment.error'
9
- | 'setu.topup.required'
10
- | 'setu.topup.method_selected'
11
- | 'setu.topup.cancelled'
12
- | 'setu.fiat.checkout_created'
13
- | 'setu.balance.updated'
5
+ | 'ottorouter.payment.required'
6
+ | 'ottorouter.payment.signing'
7
+ | 'ottorouter.payment.complete'
8
+ | 'ottorouter.payment.error'
9
+ | 'ottorouter.topup.required'
10
+ | 'ottorouter.topup.method_selected'
11
+ | 'ottorouter.topup.cancelled'
12
+ | 'ottorouter.fiat.checkout_created'
13
+ | 'ottorouter.balance.updated'
14
14
  | 'session.created'
15
15
  | 'session.deleted'
16
16
  | 'session.updated'
package/src/index.ts CHANGED
@@ -17,7 +17,7 @@ import { registerSessionFilesRoutes } from './routes/session-files.ts';
17
17
  import { registerBranchRoutes } from './routes/branch.ts';
18
18
  import { registerResearchRoutes } from './routes/research.ts';
19
19
  import { registerSessionApprovalRoute } from './routes/session-approval.ts';
20
- import { registerSetuRoutes } from './routes/setu.ts';
20
+ import { registerOttoRouterRoutes } from './routes/ottorouter.ts';
21
21
  import { registerAuthRoutes } from './routes/auth.ts';
22
22
  import { registerTunnelRoutes } from './routes/tunnel.ts';
23
23
  import { registerMCPRoutes } from './routes/mcp.ts';
@@ -81,7 +81,7 @@ function initApp() {
81
81
  registerSessionFilesRoutes(app);
82
82
  registerBranchRoutes(app);
83
83
  registerResearchRoutes(app);
84
- registerSetuRoutes(app);
84
+ registerOttoRouterRoutes(app);
85
85
  registerAuthRoutes(app);
86
86
  registerTunnelRoutes(app);
87
87
  registerMCPRoutes(app);
@@ -156,7 +156,7 @@ export function createStandaloneApp(_config?: StandaloneAppConfig) {
156
156
  registerSessionFilesRoutes(honoApp);
157
157
  registerBranchRoutes(honoApp);
158
158
  registerResearchRoutes(honoApp);
159
- registerSetuRoutes(honoApp);
159
+ registerOttoRouterRoutes(honoApp);
160
160
  registerAuthRoutes(honoApp);
161
161
  registerTunnelRoutes(honoApp);
162
162
  registerMCPRoutes(honoApp);
@@ -267,7 +267,7 @@ export function createEmbeddedApp(config: EmbeddedAppConfig = {}) {
267
267
  registerSessionFilesRoutes(honoApp);
268
268
  registerBranchRoutes(honoApp);
269
269
  registerResearchRoutes(honoApp);
270
- registerSetuRoutes(honoApp);
270
+ registerOttoRouterRoutes(honoApp);
271
271
  registerAuthRoutes(honoApp);
272
272
  registerTunnelRoutes(honoApp);
273
273
  registerMCPRoutes(honoApp);
@@ -15,7 +15,7 @@ export const authPaths = {
15
15
  type: 'object',
16
16
  properties: {
17
17
  onboardingComplete: { type: 'boolean' },
18
- setu: {
18
+ ottorouter: {
19
19
  type: 'object',
20
20
  properties: {
21
21
  configured: { type: 'boolean' },
@@ -65,7 +65,7 @@ export const authPaths = {
65
65
  },
66
66
  },
67
67
  },
68
- required: ['onboardingComplete', 'setu', 'providers'],
68
+ required: ['onboardingComplete', 'ottorouter', 'providers'],
69
69
  },
70
70
  },
71
71
  },
@@ -73,11 +73,11 @@ export const authPaths = {
73
73
  },
74
74
  },
75
75
  },
76
- '/v1/auth/setu/setup': {
76
+ '/v1/auth/ottorouter/setup': {
77
77
  post: {
78
78
  tags: ['auth'],
79
- operationId: 'setupSetuWallet',
80
- summary: 'Setup or ensure Setu wallet',
79
+ operationId: 'setupOttoRouterWallet',
80
+ summary: 'Setup or ensure OttoRouter wallet',
81
81
  responses: {
82
82
  200: {
83
83
  description: 'OK',
@@ -98,11 +98,11 @@ export const authPaths = {
98
98
  },
99
99
  },
100
100
  },
101
- '/v1/auth/setu/import': {
101
+ '/v1/auth/ottorouter/import': {
102
102
  post: {
103
103
  tags: ['auth'],
104
- operationId: 'importSetuWallet',
105
- summary: 'Import Setu wallet from private key',
104
+ operationId: 'importOttoRouterWallet',
105
+ summary: 'Import OttoRouter wallet from private key',
106
106
  requestBody: {
107
107
  required: true,
108
108
  content: {
@@ -137,11 +137,11 @@ export const authPaths = {
137
137
  },
138
138
  },
139
139
  },
140
- '/v1/auth/setu/export': {
140
+ '/v1/auth/ottorouter/export': {
141
141
  get: {
142
142
  tags: ['auth'],
143
- operationId: 'exportSetuWallet',
144
- summary: 'Export Setu wallet private key',
143
+ operationId: 'exportOttoRouterWallet',
144
+ summary: 'Export OttoRouter wallet private key',
145
145
  responses: {
146
146
  200: {
147
147
  description: 'OK',
@@ -1,9 +1,9 @@
1
- export const setuPaths = {
2
- '/v1/setu/balance': {
1
+ export const ottorouterPaths = {
2
+ '/v1/ottorouter/balance': {
3
3
  get: {
4
- tags: ['setu'],
5
- operationId: 'getSetuBalance',
6
- summary: 'Get Setu account balance',
4
+ tags: ['ottorouter'],
5
+ operationId: 'getOttoRouterBalance',
6
+ summary: 'Get OttoRouter account balance',
7
7
  description:
8
8
  'Returns wallet balance, subscription, account info, limits, and usage data',
9
9
  responses: {
@@ -82,7 +82,7 @@ export const setuPaths = {
82
82
  },
83
83
  },
84
84
  502: {
85
- description: 'Failed to fetch balance from Setu',
85
+ description: 'Failed to fetch balance from OttoRouter',
86
86
  content: {
87
87
  'application/json': {
88
88
  schema: {
@@ -96,11 +96,11 @@ export const setuPaths = {
96
96
  },
97
97
  },
98
98
  },
99
- '/v1/setu/wallet': {
99
+ '/v1/ottorouter/wallet': {
100
100
  get: {
101
- tags: ['setu'],
102
- operationId: 'getSetuWallet',
103
- summary: 'Get Setu wallet info',
101
+ tags: ['ottorouter'],
102
+ operationId: 'getOttoRouterWallet',
103
+ summary: 'Get OttoRouter wallet info',
104
104
  description:
105
105
  'Returns whether the wallet is configured and its public key',
106
106
  responses: {
@@ -123,10 +123,10 @@ export const setuPaths = {
123
123
  },
124
124
  },
125
125
  },
126
- '/v1/setu/usdc-balance': {
126
+ '/v1/ottorouter/usdc-balance': {
127
127
  get: {
128
- tags: ['setu'],
129
- operationId: 'getSetuUsdcBalance',
128
+ tags: ['ottorouter'],
129
+ operationId: 'getOttoRouterUsdcBalance',
130
130
  summary: 'Get USDC token balance',
131
131
  description:
132
132
  'Fetches USDC balance from Solana blockchain for the configured wallet',
@@ -189,9 +189,9 @@ export const setuPaths = {
189
189
  },
190
190
  },
191
191
  },
192
- '/v1/setu/topup/polar': {
192
+ '/v1/ottorouter/topup/polar': {
193
193
  post: {
194
- tags: ['setu'],
194
+ tags: ['ottorouter'],
195
195
  operationId: 'createPolarCheckout',
196
196
  summary: 'Create a Polar checkout for topping up',
197
197
  requestBody: {
@@ -233,9 +233,9 @@ export const setuPaths = {
233
233
  },
234
234
  },
235
235
  },
236
- '/v1/setu/topup/select': {
236
+ '/v1/ottorouter/topup/select': {
237
237
  post: {
238
- tags: ['setu'],
238
+ tags: ['ottorouter'],
239
239
  operationId: 'selectTopupMethod',
240
240
  summary: 'Select topup method for pending request',
241
241
  requestBody: {
@@ -287,9 +287,9 @@ export const setuPaths = {
287
287
  },
288
288
  },
289
289
  },
290
- '/v1/setu/topup/cancel': {
290
+ '/v1/ottorouter/topup/cancel': {
291
291
  post: {
292
- tags: ['setu'],
292
+ tags: ['ottorouter'],
293
293
  operationId: 'cancelTopup',
294
294
  summary: 'Cancel pending topup',
295
295
  requestBody: {
@@ -337,9 +337,9 @@ export const setuPaths = {
337
337
  },
338
338
  },
339
339
  },
340
- '/v1/setu/topup/pending': {
340
+ '/v1/ottorouter/topup/pending': {
341
341
  get: {
342
- tags: ['setu'],
342
+ tags: ['ottorouter'],
343
343
  operationId: 'getPendingTopup',
344
344
  summary: 'Get pending topup for a session',
345
345
  parameters: [
@@ -373,9 +373,9 @@ export const setuPaths = {
373
373
  },
374
374
  },
375
375
  },
376
- '/v1/setu/topup/polar/estimate': {
376
+ '/v1/ottorouter/topup/polar/estimate': {
377
377
  get: {
378
- tags: ['setu'],
378
+ tags: ['ottorouter'],
379
379
  operationId: 'getPolarTopupEstimate',
380
380
  summary: 'Get estimated fees for a Polar topup',
381
381
  parameters: [
@@ -414,9 +414,9 @@ export const setuPaths = {
414
414
  },
415
415
  },
416
416
  },
417
- '/v1/setu/topup/polar/status': {
417
+ '/v1/ottorouter/topup/polar/status': {
418
418
  get: {
419
- tags: ['setu'],
419
+ tags: ['ottorouter'],
420
420
  operationId: 'getPolarTopupStatus',
421
421
  summary: 'Get status of a Polar checkout',
422
422
  parameters: [
@@ -447,9 +447,9 @@ export const setuPaths = {
447
447
  },
448
448
  },
449
449
  },
450
- '/v1/setu/topup/razorpay/estimate': {
450
+ '/v1/ottorouter/topup/razorpay/estimate': {
451
451
  get: {
452
- tags: ['setu'],
452
+ tags: ['ottorouter'],
453
453
  operationId: 'getRazorpayTopupEstimate',
454
454
  summary: 'Get estimated fees for a Razorpay topup',
455
455
  parameters: [
@@ -482,9 +482,9 @@ export const setuPaths = {
482
482
  },
483
483
  },
484
484
  },
485
- '/v1/setu/topup/razorpay': {
485
+ '/v1/ottorouter/topup/razorpay': {
486
486
  post: {
487
- tags: ['setu'],
487
+ tags: ['ottorouter'],
488
488
  operationId: 'createRazorpayOrder',
489
489
  summary: 'Create a Razorpay order for topping up',
490
490
  requestBody: {
@@ -535,9 +535,9 @@ export const setuPaths = {
535
535
  },
536
536
  },
537
537
  },
538
- '/v1/setu/topup/razorpay/verify': {
538
+ '/v1/ottorouter/topup/razorpay/verify': {
539
539
  post: {
540
- tags: ['setu'],
540
+ tags: ['ottorouter'],
541
541
  operationId: 'verifyRazorpayPayment',
542
542
  summary: 'Verify Razorpay payment and credit balance',
543
543
  requestBody: {
@@ -13,7 +13,7 @@ import { sessionApprovalPaths } from './paths/session-approval';
13
13
  import { sessionExtrasPaths } from './paths/session-extras';
14
14
  import { sessionFilesPaths } from './paths/session-files';
15
15
  import { sessionsPaths } from './paths/sessions';
16
- import { setuPaths } from './paths/setu';
16
+ import { ottorouterPaths } from './paths/ottorouter';
17
17
  import { skillsPaths } from './paths/skills';
18
18
  import { streamPaths } from './paths/stream';
19
19
  import { terminalsPath } from './paths/terminals';
@@ -38,7 +38,7 @@ export function getOpenAPISpec() {
38
38
  { name: 'files' },
39
39
  { name: 'git' },
40
40
  { name: 'terminals' },
41
- { name: 'setu' },
41
+ { name: 'ottorouter' },
42
42
  { name: 'auth' },
43
43
  { name: 'mcp' },
44
44
  { name: 'tunnel' },
@@ -59,7 +59,7 @@ export function getOpenAPISpec() {
59
59
  ...sessionExtrasPaths,
60
60
  ...sessionFilesPaths,
61
61
  ...sessionsPaths,
62
- ...setuPaths,
62
+ ...ottorouterPaths,
63
63
  ...skillsPaths,
64
64
  ...streamPaths,
65
65
  ...terminalsPath,
@@ -4,8 +4,8 @@ import {
4
4
  getAuth,
5
5
  setAuth,
6
6
  removeAuth,
7
- ensureSetuWallet,
8
- getSetuWallet,
7
+ ensureOttoRouterWallet,
8
+ getOttoRouterWallet,
9
9
  importWallet,
10
10
  loadConfig,
11
11
  catalog,
@@ -223,7 +223,7 @@ export function registerAuthRoutes(app: Hono) {
223
223
  const auth = await getAllAuth(projectRoot);
224
224
  const cfg = await loadConfig(projectRoot);
225
225
  const onboardingComplete = await getOnboardingComplete(projectRoot);
226
- const setuWallet = await getSetuWallet(projectRoot);
226
+ const ottorouterWallet = await getOttoRouterWallet(projectRoot);
227
227
  const ghImportCapability = getGhImportCapability();
228
228
 
229
229
  const providers: Record<
@@ -269,10 +269,10 @@ export function registerAuthRoutes(app: Hono) {
269
269
 
270
270
  return c.json({
271
271
  onboardingComplete,
272
- setu: setuWallet
272
+ ottorouter: ottorouterWallet
273
273
  ? {
274
274
  configured: true,
275
- publicKey: setuWallet.publicKey,
275
+ publicKey: ottorouterWallet.publicKey,
276
276
  }
277
277
  : {
278
278
  configured: false,
@@ -287,11 +287,11 @@ export function registerAuthRoutes(app: Hono) {
287
287
  }
288
288
  });
289
289
 
290
- app.post('/v1/auth/setu/setup', async (c) => {
290
+ app.post('/v1/auth/ottorouter/setup', async (c) => {
291
291
  try {
292
292
  const projectRoot = process.cwd();
293
- const existing = await getSetuWallet(projectRoot);
294
- const wallet = await ensureSetuWallet(projectRoot);
293
+ const existing = await getOttoRouterWallet(projectRoot);
294
+ const wallet = await ensureOttoRouterWallet(projectRoot);
295
295
 
296
296
  return c.json({
297
297
  success: true,
@@ -299,13 +299,13 @@ export function registerAuthRoutes(app: Hono) {
299
299
  isNew: !existing,
300
300
  });
301
301
  } catch (error) {
302
- logger.error('Failed to setup Setu wallet', error);
302
+ logger.error('Failed to setup OttoRouter wallet', error);
303
303
  const errorResponse = serializeError(error);
304
304
  return c.json(errorResponse, errorResponse.error.status || 500);
305
305
  }
306
306
  });
307
307
 
308
- app.post('/v1/auth/setu/import', async (c) => {
308
+ app.post('/v1/auth/ottorouter/import', async (c) => {
309
309
  try {
310
310
  const { privateKey } = await c.req.json<{ privateKey: string }>();
311
311
 
@@ -316,7 +316,7 @@ export function registerAuthRoutes(app: Hono) {
316
316
  try {
317
317
  const wallet = importWallet(privateKey);
318
318
  await setAuth(
319
- 'setu',
319
+ 'ottorouter',
320
320
  { type: 'wallet', secret: privateKey },
321
321
  undefined,
322
322
  'global',
@@ -330,19 +330,19 @@ export function registerAuthRoutes(app: Hono) {
330
330
  return c.json({ error: 'Invalid private key format' }, 400);
331
331
  }
332
332
  } catch (error) {
333
- logger.error('Failed to import Setu wallet', error);
333
+ logger.error('Failed to import OttoRouter wallet', error);
334
334
  const errorResponse = serializeError(error);
335
335
  return c.json(errorResponse, errorResponse.error.status || 500);
336
336
  }
337
337
  });
338
338
 
339
- app.get('/v1/auth/setu/export', async (c) => {
339
+ app.get('/v1/auth/ottorouter/export', async (c) => {
340
340
  try {
341
341
  const projectRoot = process.cwd();
342
- const wallet = await getSetuWallet(projectRoot);
342
+ const wallet = await getOttoRouterWallet(projectRoot);
343
343
 
344
344
  if (!wallet) {
345
- return c.json({ error: 'Setu wallet not configured' }, 404);
345
+ return c.json({ error: 'OttoRouter wallet not configured' }, 404);
346
346
  }
347
347
 
348
348
  return c.json({
@@ -351,7 +351,7 @@ export function registerAuthRoutes(app: Hono) {
351
351
  privateKey: wallet.privateKey,
352
352
  });
353
353
  } catch (error) {
354
- logger.error('Failed to export Setu wallet', error);
354
+ logger.error('Failed to export OttoRouter wallet', error);
355
355
  const errorResponse = serializeError(error);
356
356
  return c.json(errorResponse, errorResponse.error.status || 500);
357
357
  }
@@ -20,7 +20,7 @@ const PROVIDERS: ProviderId[] = [
20
20
  'google',
21
21
  'openrouter',
22
22
  'opencode',
23
- 'setu',
23
+ 'ottorouter',
24
24
  ];
25
25
 
26
26
  function providerEnvVar(p: ProviderId): string | null {
@@ -28,7 +28,7 @@ function providerEnvVar(p: ProviderId): string | null {
28
28
  if (p === 'anthropic') return 'ANTHROPIC_API_KEY';
29
29
  if (p === 'google') return 'GOOGLE_GENERATIVE_AI_API_KEY';
30
30
  if (p === 'opencode') return 'OPENCODE_API_KEY';
31
- if (p === 'setu') return 'SETU_PRIVATE_KEY';
31
+ if (p === 'ottorouter') return 'OTTOROUTER_PRIVATE_KEY';
32
32
  return null;
33
33
  }
34
34
 
@@ -1,6 +1,6 @@
1
1
  import type { Hono } from 'hono';
2
2
  import {
3
- fetchSetuBalance,
3
+ fetchOttoRouterBalance,
4
4
  getPublicKeyFromPrivate,
5
5
  getAuth,
6
6
  loadConfig,
@@ -18,23 +18,23 @@ import {
18
18
  type TopupMethod,
19
19
  } from '../runtime/topup/manager.ts';
20
20
 
21
- const SETU_BASE_URL =
22
- process.env.SETU_BASE_URL || 'https://api.setu.ottocode.io';
21
+ const OTTOROUTER_BASE_URL =
22
+ process.env.OTTOROUTER_BASE_URL || 'https://api.ottorouter.org';
23
23
 
24
- function getSetuBaseUrl(): string {
25
- return SETU_BASE_URL.endsWith('/')
26
- ? SETU_BASE_URL.slice(0, -1)
27
- : SETU_BASE_URL;
24
+ function getOttoRouterBaseUrl(): string {
25
+ return OTTOROUTER_BASE_URL.endsWith('/')
26
+ ? OTTOROUTER_BASE_URL.slice(0, -1)
27
+ : OTTOROUTER_BASE_URL;
28
28
  }
29
29
 
30
- async function getSetuPrivateKey(): Promise<string | null> {
31
- if (process.env.SETU_PRIVATE_KEY) {
32
- return process.env.SETU_PRIVATE_KEY;
30
+ async function getOttoRouterPrivateKey(): Promise<string | null> {
31
+ if (process.env.OTTOROUTER_PRIVATE_KEY) {
32
+ return process.env.OTTOROUTER_PRIVATE_KEY;
33
33
  }
34
34
 
35
35
  try {
36
36
  const cfg = await loadConfig(process.cwd());
37
- const auth = await getAuth('setu', cfg.projectRoot);
37
+ const auth = await getAuth('ottorouter', cfg.projectRoot);
38
38
  if (auth?.type === 'wallet' && auth.secret) {
39
39
  return auth.secret;
40
40
  }
@@ -62,33 +62,36 @@ function buildWalletHeaders(privateKey: string): Record<string, string> {
62
62
  };
63
63
  }
64
64
 
65
- export function registerSetuRoutes(app: Hono) {
66
- app.get('/v1/setu/balance', async (c) => {
65
+ export function registerOttoRouterRoutes(app: Hono) {
66
+ app.get('/v1/ottorouter/balance', async (c) => {
67
67
  try {
68
- const privateKey = await getSetuPrivateKey();
68
+ const privateKey = await getOttoRouterPrivateKey();
69
69
  if (!privateKey) {
70
- return c.json({ error: 'Setu wallet not configured' }, 401);
70
+ return c.json({ error: 'OttoRouter wallet not configured' }, 401);
71
71
  }
72
72
 
73
- const balance = await fetchSetuBalance({ privateKey });
73
+ const balance = await fetchOttoRouterBalance({ privateKey });
74
74
  if (!balance) {
75
- return c.json({ error: 'Failed to fetch balance from Setu' }, 502);
75
+ return c.json(
76
+ { error: 'Failed to fetch balance from OttoRouter' },
77
+ 502,
78
+ );
76
79
  }
77
80
 
78
81
  return c.json(balance);
79
82
  } catch (error) {
80
- logger.error('Failed to fetch Setu balance', error);
83
+ logger.error('Failed to fetch OttoRouter balance', error);
81
84
  const errorResponse = serializeError(error);
82
85
  return c.json(errorResponse, errorResponse.error.status || 500);
83
86
  }
84
87
  });
85
88
 
86
- app.get('/v1/setu/wallet', async (c) => {
89
+ app.get('/v1/ottorouter/wallet', async (c) => {
87
90
  try {
88
- const privateKey = await getSetuPrivateKey();
91
+ const privateKey = await getOttoRouterPrivateKey();
89
92
  if (!privateKey) {
90
93
  return c.json(
91
- { error: 'Setu wallet not configured', configured: false },
94
+ { error: 'OttoRouter wallet not configured', configured: false },
92
95
  200,
93
96
  );
94
97
  }
@@ -103,17 +106,17 @@ export function registerSetuRoutes(app: Hono) {
103
106
  publicKey,
104
107
  });
105
108
  } catch (error) {
106
- logger.error('Failed to get Setu wallet info', error);
109
+ logger.error('Failed to get OttoRouter wallet info', error);
107
110
  const errorResponse = serializeError(error);
108
111
  return c.json(errorResponse, errorResponse.error.status || 500);
109
112
  }
110
113
  });
111
114
 
112
- app.get('/v1/setu/usdc-balance', async (c) => {
115
+ app.get('/v1/ottorouter/usdc-balance', async (c) => {
113
116
  try {
114
- const privateKey = await getSetuPrivateKey();
117
+ const privateKey = await getOttoRouterPrivateKey();
115
118
  if (!privateKey) {
116
- return c.json({ error: 'Setu wallet not configured' }, 401);
119
+ return c.json({ error: 'OttoRouter wallet not configured' }, 401);
117
120
  }
118
121
 
119
122
  const publicKey = getPublicKeyFromPrivate(privateKey);
@@ -121,7 +124,7 @@ export function registerSetuRoutes(app: Hono) {
121
124
  return c.json({ error: 'Invalid private key' }, 400);
122
125
  }
123
126
 
124
- const baseUrl = getSetuBaseUrl();
127
+ const baseUrl = getOttoRouterBaseUrl();
125
128
  const response = await fetch(
126
129
  `${baseUrl}/v1/wallet/${publicKey}/balances?limit=100&showNative=false&showNfts=false&showZeroBalance=false`,
127
130
  {
@@ -161,14 +164,14 @@ export function registerSetuRoutes(app: Hono) {
161
164
  }
162
165
  });
163
166
 
164
- app.get('/v1/setu/topup/polar/estimate', async (c) => {
167
+ app.get('/v1/ottorouter/topup/polar/estimate', async (c) => {
165
168
  try {
166
169
  const amount = c.req.query('amount');
167
170
  if (!amount) {
168
171
  return c.json({ error: 'Missing amount parameter' }, 400);
169
172
  }
170
173
 
171
- const baseUrl = getSetuBaseUrl();
174
+ const baseUrl = getOttoRouterBaseUrl();
172
175
  const response = await fetch(
173
176
  `${baseUrl}/v1/topup/polar/estimate?amount=${amount}`,
174
177
  {
@@ -190,11 +193,11 @@ export function registerSetuRoutes(app: Hono) {
190
193
  }
191
194
  });
192
195
 
193
- app.post('/v1/setu/topup/polar', async (c) => {
196
+ app.post('/v1/ottorouter/topup/polar', async (c) => {
194
197
  try {
195
- const privateKey = await getSetuPrivateKey();
198
+ const privateKey = await getOttoRouterPrivateKey();
196
199
  if (!privateKey) {
197
- return c.json({ error: 'Setu wallet not configured' }, 401);
200
+ return c.json({ error: 'OttoRouter wallet not configured' }, 401);
198
201
  }
199
202
 
200
203
  const body = await c.req.json();
@@ -212,7 +215,7 @@ export function registerSetuRoutes(app: Hono) {
212
215
  }
213
216
 
214
217
  const walletHeaders = buildWalletHeaders(privateKey);
215
- const baseUrl = getSetuBaseUrl();
218
+ const baseUrl = getOttoRouterBaseUrl();
216
219
 
217
220
  const response = await fetch(`${baseUrl}/v1/topup/polar`, {
218
221
  method: 'POST',
@@ -236,7 +239,7 @@ export function registerSetuRoutes(app: Hono) {
236
239
  }
237
240
  });
238
241
 
239
- app.post('/v1/setu/topup/select', async (c) => {
242
+ app.post('/v1/ottorouter/topup/select', async (c) => {
240
243
  try {
241
244
  const body = await c.req.json();
242
245
  const { sessionId, method } = body as {
@@ -264,7 +267,7 @@ export function registerSetuRoutes(app: Hono) {
264
267
  }
265
268
 
266
269
  publish({
267
- type: 'setu.topup.method_selected',
270
+ type: 'ottorouter.topup.method_selected',
268
271
  sessionId,
269
272
  payload: { method },
270
273
  });
@@ -277,7 +280,7 @@ export function registerSetuRoutes(app: Hono) {
277
280
  }
278
281
  });
279
282
 
280
- app.post('/v1/setu/topup/cancel', async (c) => {
283
+ app.post('/v1/ottorouter/topup/cancel', async (c) => {
281
284
  try {
282
285
  const body = await c.req.json();
283
286
  const { sessionId, reason } = body as {
@@ -301,7 +304,7 @@ export function registerSetuRoutes(app: Hono) {
301
304
  }
302
305
 
303
306
  publish({
304
- type: 'setu.topup.cancelled',
307
+ type: 'ottorouter.topup.cancelled',
305
308
  sessionId,
306
309
  payload: { reason: reason ?? 'User cancelled' },
307
310
  });
@@ -314,7 +317,7 @@ export function registerSetuRoutes(app: Hono) {
314
317
  }
315
318
  });
316
319
 
317
- app.get('/v1/setu/topup/pending', async (c) => {
320
+ app.get('/v1/ottorouter/topup/pending', async (c) => {
318
321
  try {
319
322
  const sessionId = c.req.query('sessionId');
320
323
  if (!sessionId) {
@@ -341,14 +344,14 @@ export function registerSetuRoutes(app: Hono) {
341
344
  }
342
345
  });
343
346
 
344
- app.get('/v1/setu/topup/polar/status', async (c) => {
347
+ app.get('/v1/ottorouter/topup/polar/status', async (c) => {
345
348
  try {
346
349
  const checkoutId = c.req.query('checkoutId');
347
350
  if (!checkoutId) {
348
351
  return c.json({ error: 'Missing checkoutId parameter' }, 400);
349
352
  }
350
353
 
351
- const baseUrl = getSetuBaseUrl();
354
+ const baseUrl = getOttoRouterBaseUrl();
352
355
  const response = await fetch(
353
356
  `${baseUrl}/v1/topup/polar/status?checkoutId=${checkoutId}`,
354
357
  {
@@ -370,14 +373,14 @@ export function registerSetuRoutes(app: Hono) {
370
373
  }
371
374
  });
372
375
 
373
- app.get('/v1/setu/topup/razorpay/estimate', async (c) => {
376
+ app.get('/v1/ottorouter/topup/razorpay/estimate', async (c) => {
374
377
  try {
375
378
  const amount = c.req.query('amount');
376
379
  if (!amount) {
377
380
  return c.json({ error: 'Missing amount parameter' }, 400);
378
381
  }
379
382
 
380
- const baseUrl = getSetuBaseUrl();
383
+ const baseUrl = getOttoRouterBaseUrl();
381
384
  const response = await fetch(
382
385
  `${baseUrl}/v1/topup/razorpay/estimate?amount=${amount}`,
383
386
  {
@@ -399,11 +402,11 @@ export function registerSetuRoutes(app: Hono) {
399
402
  }
400
403
  });
401
404
 
402
- app.post('/v1/setu/topup/razorpay', async (c) => {
405
+ app.post('/v1/ottorouter/topup/razorpay', async (c) => {
403
406
  try {
404
- const privateKey = await getSetuPrivateKey();
407
+ const privateKey = await getOttoRouterPrivateKey();
405
408
  if (!privateKey) {
406
- return c.json({ error: 'Setu wallet not configured' }, 401);
409
+ return c.json({ error: 'OttoRouter wallet not configured' }, 401);
407
410
  }
408
411
 
409
412
  const body = await c.req.json();
@@ -414,7 +417,7 @@ export function registerSetuRoutes(app: Hono) {
414
417
  }
415
418
 
416
419
  const walletHeaders = buildWalletHeaders(privateKey);
417
- const baseUrl = getSetuBaseUrl();
420
+ const baseUrl = getOttoRouterBaseUrl();
418
421
 
419
422
  const response = await fetch(`${baseUrl}/v1/topup/razorpay`, {
420
423
  method: 'POST',
@@ -438,11 +441,11 @@ export function registerSetuRoutes(app: Hono) {
438
441
  }
439
442
  });
440
443
 
441
- app.post('/v1/setu/topup/razorpay/verify', async (c) => {
444
+ app.post('/v1/ottorouter/topup/razorpay/verify', async (c) => {
442
445
  try {
443
- const privateKey = await getSetuPrivateKey();
446
+ const privateKey = await getOttoRouterPrivateKey();
444
447
  if (!privateKey) {
445
- return c.json({ error: 'Setu wallet not configured' }, 401);
448
+ return c.json({ error: 'OttoRouter wallet not configured' }, 401);
446
449
  }
447
450
 
448
451
  const body = await c.req.json();
@@ -458,7 +461,7 @@ export function registerSetuRoutes(app: Hono) {
458
461
  }
459
462
 
460
463
  const walletHeaders = buildWalletHeaders(privateKey);
461
- const baseUrl = getSetuBaseUrl();
464
+ const baseUrl = getOttoRouterBaseUrl();
462
465
 
463
466
  const response = await fetch(`${baseUrl}/v1/topup/razorpay/verify`, {
464
467
  method: 'POST',
@@ -137,7 +137,7 @@ async function processAskRequest(
137
137
  openrouter: { enabled: true },
138
138
  opencode: { enabled: true },
139
139
  copilot: { enabled: true },
140
- setu: { enabled: true },
140
+ ottorouter: { enabled: true },
141
141
  zai: { enabled: true },
142
142
  'zai-coding': { enabled: true },
143
143
  moonshot: { enabled: true },
@@ -3,7 +3,10 @@ import { getAnthropicInstance } from './anthropic.ts';
3
3
  import { resolveOpenAIModel } from './openai.ts';
4
4
  import { resolveGoogleModel } from './google.ts';
5
5
  import { resolveOpenRouterModel } from './openrouter.ts';
6
- import { resolveSetuModel, type ResolveSetuModelOptions } from './setu.ts';
6
+ import {
7
+ resolveOttoRouterModel,
8
+ type ResolveOttoRouterModelOptions,
9
+ } from './ottorouter.ts';
7
10
  import { getZaiInstance, getZaiCodingInstance } from './zai.ts';
8
11
  import { resolveOpencodeModel } from './opencode.ts';
9
12
  import { getMoonshotInstance } from './moonshot.ts';
@@ -20,8 +23,8 @@ export async function resolveModel(
20
23
  systemPrompt?: string;
21
24
  sessionId?: string;
22
25
  messageId?: string;
23
- topupApprovalMode?: ResolveSetuModelOptions['topupApprovalMode'];
24
- autoPayThresholdUsd?: ResolveSetuModelOptions['autoPayThresholdUsd'];
26
+ topupApprovalMode?: ResolveOttoRouterModelOptions['topupApprovalMode'];
27
+ autoPayThresholdUsd?: ResolveOttoRouterModelOptions['autoPayThresholdUsd'];
25
28
  },
26
29
  ) {
27
30
  if (provider === 'openai') {
@@ -43,8 +46,8 @@ export async function resolveModel(
43
46
  if (provider === 'copilot') {
44
47
  return resolveCopilotModel(model, cfg);
45
48
  }
46
- if (provider === 'setu') {
47
- return await resolveSetuModel(model, options?.sessionId, {
49
+ if (provider === 'ottorouter') {
50
+ return await resolveOttoRouterModel(model, options?.sessionId, {
48
51
  messageId: options?.messageId,
49
52
  topupApprovalMode: options?.topupApprovalMode,
50
53
  autoPayThresholdUsd: options?.autoPayThresholdUsd,
@@ -1,6 +1,6 @@
1
1
  import {
2
- createSetu,
3
- type SetuPaymentCallbacks,
2
+ createOttoRouter,
3
+ type OttoRouterPaymentCallbacks,
4
4
  getAuth,
5
5
  loadConfig,
6
6
  } from '@ottocode/sdk';
@@ -14,19 +14,19 @@ import {
14
14
 
15
15
  const MIN_TOPUP_USD = 5;
16
16
 
17
- export interface ResolveSetuModelOptions {
17
+ export interface ResolveOttoRouterModelOptions {
18
18
  messageId?: string;
19
19
  topupApprovalMode?: 'auto' | 'approval';
20
20
  autoPayThresholdUsd?: number;
21
21
  }
22
22
 
23
- async function getSetuPrivateKey(): Promise<string> {
24
- if (process.env.SETU_PRIVATE_KEY) {
25
- return process.env.SETU_PRIVATE_KEY;
23
+ async function getOttoRouterPrivateKey(): Promise<string> {
24
+ if (process.env.OTTOROUTER_PRIVATE_KEY) {
25
+ return process.env.OTTOROUTER_PRIVATE_KEY;
26
26
  }
27
27
  try {
28
28
  const cfg = await loadConfig(process.cwd());
29
- const auth = await getAuth('setu', cfg.projectRoot);
29
+ const auth = await getAuth('ottorouter', cfg.projectRoot);
30
30
  if (auth?.type === 'wallet' && auth.secret) {
31
31
  return auth.secret;
32
32
  }
@@ -34,58 +34,58 @@ async function getSetuPrivateKey(): Promise<string> {
34
34
  return '';
35
35
  }
36
36
 
37
- export async function resolveSetuModel(
37
+ export async function resolveOttoRouterModel(
38
38
  model: string,
39
39
  sessionId?: string,
40
- options: ResolveSetuModelOptions = {},
40
+ options: ResolveOttoRouterModelOptions = {},
41
41
  ) {
42
- const privateKey = await getSetuPrivateKey();
42
+ const privateKey = await getOttoRouterPrivateKey();
43
43
  if (!privateKey) {
44
44
  throw new Error(
45
- 'Setu provider requires SETU_PRIVATE_KEY (base58 Solana secret).',
45
+ 'OttoRouter provider requires OTTOROUTER_PRIVATE_KEY (base58 Solana secret).',
46
46
  );
47
47
  }
48
- const baseURL = process.env.SETU_BASE_URL;
49
- const rpcURL = process.env.SETU_SOLANA_RPC_URL;
48
+ const baseURL = process.env.OTTOROUTER_BASE_URL;
49
+ const rpcURL = process.env.OTTOROUTER_SOLANA_RPC_URL;
50
50
  const {
51
51
  messageId,
52
52
  topupApprovalMode = 'approval',
53
53
  autoPayThresholdUsd = MIN_TOPUP_USD,
54
54
  } = options;
55
55
 
56
- const callbacks: SetuPaymentCallbacks = sessionId
56
+ const callbacks: OttoRouterPaymentCallbacks = sessionId
57
57
  ? {
58
58
  onPaymentRequired: (amountUsd, currentBalance) => {
59
59
  publish({
60
- type: 'setu.payment.required',
60
+ type: 'ottorouter.payment.required',
61
61
  sessionId,
62
62
  payload: { amountUsd, currentBalance },
63
63
  });
64
64
  },
65
65
  onPaymentSigning: () => {
66
66
  publish({
67
- type: 'setu.payment.signing',
67
+ type: 'ottorouter.payment.signing',
68
68
  sessionId,
69
69
  payload: {},
70
70
  });
71
71
  },
72
72
  onPaymentComplete: (data) => {
73
73
  publish({
74
- type: 'setu.payment.complete',
74
+ type: 'ottorouter.payment.complete',
75
75
  sessionId,
76
76
  payload: data,
77
77
  });
78
78
  },
79
79
  onPaymentError: (error) => {
80
80
  publish({
81
- type: 'setu.payment.error',
81
+ type: 'ottorouter.payment.error',
82
82
  sessionId,
83
83
  payload: { error },
84
84
  });
85
85
  },
86
86
  onBalanceUpdate: (update) => {
87
87
  publish({
88
- type: 'setu.balance.updated',
88
+ type: 'ottorouter.balance.updated',
89
89
  sessionId,
90
90
  payload: update,
91
91
  });
@@ -97,7 +97,7 @@ export async function resolveSetuModel(
97
97
  );
98
98
 
99
99
  publish({
100
- type: 'setu.topup.required',
100
+ type: 'ottorouter.topup.required',
101
101
  sessionId,
102
102
  payload: {
103
103
  messageId,
@@ -118,7 +118,7 @@ export async function resolveSetuModel(
118
118
  }
119
119
  : {};
120
120
 
121
- const setu = createSetu({
121
+ const ottorouter = createOttoRouter({
122
122
  auth: { privateKey },
123
123
  baseURL,
124
124
  rpcURL,
@@ -130,5 +130,5 @@ export async function resolveSetuModel(
130
130
  },
131
131
  });
132
132
 
133
- return setu.model(model);
133
+ return ottorouter.model(model);
134
134
  }
@@ -14,7 +14,7 @@ const FALLBACK_ORDER: ProviderId[] = [
14
14
  'google',
15
15
  'opencode',
16
16
  'openrouter',
17
- 'setu',
17
+ 'ottorouter',
18
18
  ];
19
19
 
20
20
  type SelectionInput = {
@@ -71,7 +71,7 @@ export function resolveUsageProvider(
71
71
  model: string,
72
72
  ): ProviderId {
73
73
  if (
74
- provider !== 'setu' &&
74
+ provider !== 'ottorouter' &&
75
75
  provider !== 'openrouter' &&
76
76
  provider !== 'opencode'
77
77
  ) {
@@ -28,7 +28,7 @@ export function createErrorHandler(
28
28
  | undefined;
29
29
  const causeError = errObj?.cause as Record<string, unknown> | undefined;
30
30
 
31
- // Check for SETU_FIAT_SELECTED code specifically (not string matching)
31
+ // Check for OTTOROUTER_FIAT_SELECTED code specifically (not string matching)
32
32
  const errorCode =
33
33
  (errObj?.code as string) ??
34
34
  ((errObj?.error as Record<string, unknown>)?.code as string) ??
@@ -72,7 +72,7 @@ export function createErrorHandler(
72
72
  (causeError?.message as string) ??
73
73
  '';
74
74
 
75
- const isFiatSelected = errorCode === 'SETU_FIAT_SELECTED';
75
+ const isFiatSelected = errorCode === 'OTTOROUTER_FIAT_SELECTED';
76
76
 
77
77
  // Handle fiat payment selected - this is not an error, just a signal to pause
78
78
  if (isFiatSelected) {
@@ -140,7 +140,7 @@ export function createErrorHandler(
140
140
 
141
141
  // Emit a special event so UI knows to show topup modal
142
142
  publish({
143
- type: 'setu.fiat.checkout_created',
143
+ type: 'ottorouter.fiat.checkout_created',
144
144
  sessionId: opts.sessionId,
145
145
  payload: {
146
146
  messageId: opts.assistantMessageId,