@token2chat/t2c 0.2.0 → 0.2.2

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.
@@ -6,7 +6,8 @@
6
6
  import fs from "node:fs/promises";
7
7
  import path from "node:path";
8
8
  import os from "node:os";
9
- import { loadOrCreateProxySecret } from "../config.js";
9
+ import { loadOrCreateProxySecret, WALLET_PATH, formatUnits } from "../config.js";
10
+ import { CashuStore } from "../cashu-store.js";
10
11
  /**
11
12
  * Default models when Gate is unreachable.
12
13
  * IDs use dash format (proxy transforms to slash for Gate/OpenRouter).
@@ -66,31 +67,13 @@ async function getConfigPath() {
66
67
  }
67
68
  /**
68
69
  * Merge Token2Chat configuration into existing OpenClaw config.
69
- * Handles:
70
- * - Arrays and nested objects
71
- * - Existing token2chat config (overwrites, doesn't duplicate)
70
+ *
71
+ * Only adds the token2chat models provider — does NOT modify
72
+ * agents.defaults.model or agents.defaults.models so existing
73
+ * primary/fallback routing is preserved.
72
74
  */
73
75
  function mergeToken2ChatConfig(existingConfig, t2cConfig, gateModels, apiKey) {
74
76
  const config = { ...existingConfig };
75
- // Ensure plugins.entries exists
76
- if (!config.plugins || typeof config.plugins !== "object") {
77
- config.plugins = {};
78
- }
79
- const plugins = config.plugins;
80
- if (!plugins.entries || typeof plugins.entries !== "object") {
81
- plugins.entries = {};
82
- }
83
- const entries = plugins.entries;
84
- // Set/overwrite token2chat plugin config
85
- entries.token2chat = {
86
- enabled: true,
87
- config: {
88
- gateUrl: t2cConfig.gateUrl,
89
- mintUrl: t2cConfig.mintUrl,
90
- proxyPort: t2cConfig.proxyPort,
91
- walletPath: t2cConfig.walletPath,
92
- },
93
- };
94
77
  // Ensure models.providers exists
95
78
  if (!config.models || typeof config.models !== "object") {
96
79
  config.models = {};
@@ -101,12 +84,16 @@ function mergeToken2ChatConfig(existingConfig, t2cConfig, gateModels, apiKey) {
101
84
  }
102
85
  const providers = models.providers;
103
86
  // Set/overwrite token2chat provider config
87
+ const activeModels = gateModels.length > 0 ? gateModels : DEFAULT_MODELS;
104
88
  providers.token2chat = {
105
89
  baseUrl: `http://127.0.0.1:${t2cConfig.proxyPort}/v1`,
106
90
  apiKey,
107
91
  api: "openai-completions",
108
- models: gateModels.length > 0 ? gateModels : DEFAULT_MODELS,
92
+ models: activeModels,
109
93
  };
94
+ // Do NOT touch agents.defaults — the user's primary model and
95
+ // fallback chain should stay intact. Token2Chat models are available
96
+ // via the "token2chat/" provider prefix (e.g. token2chat/anthropic-claude-sonnet-4).
110
97
  return config;
111
98
  }
112
99
  export const openclawConnector = {
@@ -175,13 +162,32 @@ export const openclawConnector = {
175
162
  if (existingContent) {
176
163
  console.log(` Backup: ${backupPath}`);
177
164
  }
165
+ // Show wallet balance for onboarding
166
+ try {
167
+ const wallet = await CashuStore.load(WALLET_PATH, config.mintUrl);
168
+ console.log(`\n💰 Wallet balance: ${formatUnits(wallet.balance)}`);
169
+ }
170
+ catch {
171
+ console.log("\n💰 Wallet: not funded yet");
172
+ console.log(` Fund your wallet: t2c mint <amount>`);
173
+ console.log(` Mint URL: ${config.mintUrl}`);
174
+ }
175
+ // Show available model IDs for easy copy-paste
176
+ const activeModels = gateModels.length > 0 ? gateModels : DEFAULT_MODELS;
177
+ const modelList = activeModels.map((m) => `token2chat/${m.id}`);
178
178
  console.log("\n📋 Next steps:\n");
179
179
  console.log(" 1. Restart OpenClaw gateway:");
180
180
  console.log(" openclaw gateway restart\n");
181
- console.log(" 2. Start the t2c proxy:");
181
+ console.log(" 2. Make sure the t2c proxy is running:");
182
182
  console.log(" t2c service start\n");
183
- console.log(" 3. Use Token2Chat models with:");
184
- console.log(" token2chat/anthropic-claude-sonnet-4\n");
183
+ console.log(" 3. Use Token2Chat models (via provider prefix):");
184
+ for (const mid of modelList) {
185
+ console.log(` ${mid}`);
186
+ }
187
+ console.log("");
188
+ console.log(" 4. (Optional) Add as fallback in openclaw.json:");
189
+ console.log(' agents.defaults.model.fallbacks → ["token2chat/anthropic-claude-sonnet-4", ...]');
190
+ console.log("");
185
191
  },
186
192
  async verify() {
187
193
  // Check if config has our entries
@@ -189,11 +195,9 @@ export const openclawConnector = {
189
195
  const configPath = await getConfigPath();
190
196
  const content = await fs.readFile(configPath, "utf-8");
191
197
  const doc = JSON.parse(content);
192
- const plugins = doc?.plugins;
193
- const entries = plugins?.entries;
194
198
  const models = doc?.models;
195
199
  const providers = models?.providers;
196
- return (entries?.token2chat !== undefined && providers?.token2chat !== undefined);
200
+ return providers?.token2chat !== undefined;
197
201
  }
198
202
  catch {
199
203
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@token2chat/t2c",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "t2c - Pay-per-request LLM access via Cashu ecash",
@@ -27,7 +27,7 @@
27
27
  "cli"
28
28
  ],
29
29
  "bin": {
30
- "t2c": "./dist/index.js"
30
+ "t2c": "dist/index.js"
31
31
  },
32
32
  "main": "./dist/index.js",
33
33
  "types": "./dist/index.d.ts",