金沙Token (JinSha Token)
⚡️ 实时余额:架构与设计现状:金沙网关不支持 WebSocket金沙(one-api / new-api 体系)不提供 WebSocket / SSE / 任何 push 接口。客户端能做的只有轮询。本扩展默认 架构:单一来源,避免重复拉
关键设计:
调节轮询频率
想真"实时"怎么办?需要金沙运营改:
本扩展可以5 分钟内适配 WebSocket / SSE 推送,只要服务端支持。详见 📑 目录功能一览
✨ UI 设计原则(macOS 风格)Token 体系(
|
| 决策 | 为什么 |
|---|---|
| Hero 卡片 3px 金色 accent stripe | 一眼能看出"这是主信息",对应 Apple Health App 的设计 |
| Live 指示器 + 1Hz tick | 让用户感知"数字在跳",比纯数字更有"实时感" |
| 数字 flash 动画 | 余额变化时第一帧就能看到(即使数值小到 0.01 元) |
| Tabular-nums | font-variant-numeric: tabular-nums —— 数字等宽,跳动时不抖 |
| Skeleton loading | 比 spinner 优雅;避免"空白 200ms 然后突然冒数字"的视觉跳跃 |
| 圆形 icon-btn | 视觉重量比方块轻;不抢 Hero 卡片风头 |
| 连接色:subtle + 单一 | 只有"涨=绿、跌=红、警告=黄、金色=品牌"4 个语义色,剩下全是灰阶 |
| Activity Bar 隐藏时停轮询 | 不用面板就不发请求 —— 0 资源浪费 |
配色取自 VS Code 主题
--bg: var(--vscode-editor-background) /* 自动跟主题切换 */
--fg: var(--vscode-editor-foreground)
--card: var(--vscode-editorWidget-background)
--primary: var(--vscode-button-background)
在 light / dark / high-contrast 任何主题下都自然融入,不需要单独适配。
安装
普通用户:装 VSIX
从本仓库的 Releases 页面下载最新的 jinsha-token-*.vsix 文件,然后任选一种方式安装:
# Cursor
cursor --install-extension /path/to/jinsha-token-0.1.0.vsix
# VS Code
code --install-extension /path/to/jinsha-token-0.1.0.vsix
或在 VS Code / Cursor 内:Extensions 面板 → 右上角 ⋯ → Install from VSIX…,选择文件即可。
⚠️ 首次安装需要重启编辑器才能让
onStartupFinished触发扩展激活。
开发者:从源码跑
git clone https://github.com/jinshaxinxi/jinsha-token.git
cd jinsha-token
npm install
npm run build # 一次性生产构建
# 或者
npm run watch # 双进程 watch:ext + webview,热更新
然后在 VS Code / Cursor 中打开 jinsha-token/ 目录,按 F5 启动调试,会自动开一个 Extension Development Host 窗口——左侧 Activity Bar 找到金色沙漏图标 "金沙Token" 即可。
使用指南
第一步:获取 API KEY
登录 jinshaxinxi.cn 控制台:
- 普通密钥
sk-*:控制台 → API 密钥 → 创建。仅可调用模型,查不到余额。 - 管理 access token:控制台 → 系统管理 → 用户管理 → 自己的 access_token。可以查余额、消耗、切换账户默认模型。
💡 想看余额就必须用管理 token。普通 sk 用户的面板会显示 "此密钥无法查询余额" 的横幅(这是金沙网关的权限限制,不是本扩展的 bug)。
第二步:绑定
在 Cursor / VS Code 中:
- 左侧 Activity Bar 找到金色沙漏图标,点击打开 "金沙面板"
- 点击 绑定金沙 API KEY
- 选择 KEY 类型:
- 普通用户密钥(
sk-...开头):粘贴 sk 密钥 - 金沙管理 token:粘贴 access token
- 普通用户密钥(
- 扩展会立即验证一次(用
/v1/models或余额端点) - 绑定成功后会立刻拉一次余额 + 模型列表 + 历史
也可以命令面板 Cmd+Shift+P(macOS)/Ctrl+Shift+P(Windows/Linux)→ 输入 金沙Token。
第三步:日常使用
| 场景 | 操作 |
|---|---|
| 想看最新余额 | 面板里的 刷新 按钮 / 命令 金沙Token: 刷新账户余额 |
| 想切换到别的模型 | 面板模型下拉框 / 命令 金沙Token: 切换当前模型 |
| 想看消费趋势 | 面板右上的 1h / 24h / 7d / 30d 时间窗切换 |
| 想打开网页版价目表 | 命令 金沙Token: 打开金沙面板(指向配置 pricingUrl) |
| 想换语言 | 面板右上角中英切换 / 配置 jinshaToken.language |
| 想解绑 | 命令 金沙Token: 解绑金沙 API KEY |
| 余额低于 5 元 | 自动弹窗,可一键跳转到 jinshaxinxi.cn 充值 |
金沙接口契约(实测)
测试 token sk-7yzkrlhi7b...(普通 sk 密钥)实测结果如下,host = https://jinshaxinxi.cn:
| 用途 | 方法 | 路径 | 鉴权 | sk 可用 | admin 可用 | 备注 |
|---|---|---|---|---|---|---|
| 公开定价 | GET | /api/pricing |
无 | ✅ | ✅ | 返回 {auto_groups, data:[{model_name, quota_type, model_ratio, completion_ratio, cache_ratio, enable_groups, supported_endpoint_types, pricing_version}]} |
| OpenAI 兼容模型 | GET | /api/v1/models |
sk 或 admin | ✅ | ✅ | {data:[{id, object:'model', owned_by, supported_endpoint_types}]} |
| OpenAI 兼容调用 | POST | /api/v1/chat/completions |
sk 或 admin | ✅ | ✅ | 部分模型返回 503 model_not_found(渠道暂不可用) |
| 余额 / 自我 / 用户仪表盘 | GET | /api/user/self、/api/user/dashboard、/api/user/models、/api/user/token |
admin | ❌ 401/403 | ✅ | 客户端对 4 个端点依次探针,任一成功即用 |
| 根域 OpenAI 风格 | GET | /v1/credits、/v1/dashboard/billing/credit_grants 等 |
admin | ❌ SPA HTML | ❌ SPA HTML | 金沙新版网关已弃用——根域 /v1/* 被前端 SPA 拦截,返回 HTML 而不是 JSON |
关键发现
- 金沙是 one-api / new-api 兼容网关,但新版已不再支持根域
/v1/credits。客户端多端点探针仍保留这些是为了兼容旧网关。 - 普通
sk-*用户密钥无法查询余额——需要在金沙控制台登录后获取管理 access token。 /v1/models返回的模型不一定都能调通——返回模型只是"可见性",实际能不能调要看背后"渠道(distributor)"是否在线。gpt-5经常 503 model_not_found 但gpt-5.5-chat-completions通常可用。- 部分模型会返回
reasoning_content字段(思维链),webview 会单独高亮。
客户端多端点探针顺序
余额查询依次尝试:
1) /v1/credits — OpenAI 风格(兼容旧网关)
2) /v1/dashboard/billing/credit_grants — one-api 风格(兼容旧网关)
3) /api/user/dashboard — new-api 风格
4) /api/user/self — new-api 风格(含 quota)
任一返回有效余额即用;全部失败时:
- sk 密钥:返回
source: 'unavailable',webview 显示提示横幅 - admin token:抛出错误
quota 单位换算
new-api 默认 quota 字段是 1/500000 元 的内部单位。当接口返回的 quota > 1e6 时,客户端会自动除以 500000 换算成元。
命令一览
| 命令 ID | 命令面板标题 | 说明 |
|---|---|---|
jinshaToken.bindKey |
绑定金沙 API KEY | 选择 sk / admin 类型并粘贴 |
jinshaToken.unbindKey |
解绑金沙 API KEY | 二次确认 |
jinshaToken.refreshBalance |
刷新账户余额 | 手动触发 |
jinshaToken.openPanel |
打开金沙面板 | 打开 Activity Bar 中的 webview |
jinshaToken.switchModel |
切换当前模型 | quickPick 选择 |
jinshaToken.openPricing |
打开金沙模型价目表 | 从面板"查看价目表"按钮调用,命令面板中隐藏 |
jinshaToken.startMockServer |
启动本地 Mock 服务器 | 仅在 useMockServer=false 时出现在命令面板 |
jinshaToken.stopMockServer |
停止本地 Mock 服务器 | 仅在 useMockServer=true 时出现 |
配置项
在 VS Code / Cursor 设置里搜索 "金沙Token",或直接编辑 settings.json:
{
// === 网络 ===
"jinshaToken.apiBaseUrl": "https://jinshaxinxi.cn",
"jinshaToken.pricingUrl": "https://jinshaxinxi.cn/pricing",
// === 轮询与超时 ===
"jinshaToken.balancePollInterval": 30000, // 余额轮询间隔(ms,最小 5000)
"jinshaToken.requestTimeoutMs": 15000, // 请求超时(ms,最小 1000)
// === 阈值 ===
"jinshaToken.lowBalanceThreshold": 5, // 余额低于此值弹窗提醒(元)
// === 界面 ===
"jinshaToken.language": "zh-CN", // "zh-CN" | "en-US"
// === 本地 Mock(仅开发)===
"jinshaToken.useMockServer": false,
"jinshaToken.mockServerPort": 4000 // 1-65535
}
⚠️
apiBaseUrl的默认值是https://jinshaxinxi.cn(不带/api/v1)——本扩展代码里的端点路径已自带/api/...前缀,不要再重复添加。
项目结构
jinsha-token/
├── package.json # 扩展元信息 + 命令 + 配置项
├── src/
│ ├── extension.ts # 入口:activate / deactivate
│ ├── api/jinsha.ts # JinshaClient:多端点探针 + 归一化
│ ├── commands/index.ts # 注册命令 + 处理 webview 消息
│ ├── services/polling.ts # 余额轮询服务(interval 管理)
│ ├── i18n/
│ │ ├── index.ts # 当前语言 + 监听 vscode.env + t()
│ │ └── messages.ts # zh-CN / en-US 文案
│ ├── types/index.ts # 主进程 / 前端共享类型
│ ├── utils/
│ │ ├── config.ts # 读取 jinshaToken.* 配置
│ │ ├── prompt.ts # 弹窗 / 错误 / 信息提示
│ │ └── storage.ts # SecretStorage + 余额历史(720 点 LRU)
│ └── webview/
│ ├── index.html # 模板(HtmlWebpackPlugin 注入)
│ ├── index.tsx # React 入口
│ ├── i18n.ts # webview 端 i18n hook
│ ├── vscode.ts # postMessage 桥
│ ├── components/
│ │ ├── App.tsx # 顶层布局 + 状态机
│ │ ├── BindView.tsx # 绑定 KEY 视图
│ │ ├── Dashboard.tsx # 主面板(余额 + 模型 + 趋势)
│ │ ├── Sparkline.tsx # SVG 趋势图(Catmull-Rom 平滑曲线)
│ │ ├── HistoryStats.tsx # 峰值 / 谷值 / 24h 净变化
│ │ └── Toast.tsx # 顶部 toast 通知
│ ├── manifest.json
│ └── styles/global.css
├── resources/
│ ├── icon.png # 发布用 PNG
│ └── icon.svg # Activity Bar 用高保真金色沙漏
├── webpack/
│ ├── extension.config.js # 主进程打包:target=node,输出 dist/extension.js
│ └── webview.config.js # webview 打包:target=web,输出 dist/webview/
├── scripts/
│ ├── mock-server.ts # 本地 Mock 服务(开发联调)
│ ├── dev-webview.ts
│ └── check-env.ts
├── .vscodeignore # vsce 打包时排除源码/构建工具
├── LICENSE
└── README.md
截图来源
resources/screenshots/ 下的所有图片都是纯 SVG 矢量用 scripts/generate-screenshots.ts 生成(颜色 1:1 还原 src/webview/styles/global.css 的 CSS 变量,模型价格来自真实 headless-smoke.ts 实测数据)。需要 PNG 时跑 npx ts-node scripts/svg-to-png.ts(依赖 @resvg/resvg-js,零原生依赖)。
更新截图时只需:
npm run screenshots:png
README.md 顶部的预览图也会自动同步。
🔑 怎么获取能查余额的"管理 access token"?
金沙(jinshaxinxi.cn)网关基于 one-api / new-api 设计,按 token 角色分权限:
| Token 类型 | 前缀 | 能调用模型 | 能查余额 |
|---|---|---|---|
| 普通用户密钥 (sk-key) | sk-… |
✅ | ❌ |
| 管理 access token | 通常是 JWT 或 32+ 位 hex | ✅ | ✅ |
也就是说:你只能拿到 sk- 密钥时,永远查不到余额。要看余额必须用控制台登录后拿到的那串管理 token。
操作步骤(5 步,2 分钟)
- 浏览器打开 https://jinshaxinxi.cn
- 登录(不是点 "获取 API KEY"——那是 sk- 密钥;你要登录到控制台)
- 进入控制台首页,页面顶部或左侧找到 "Access Token" / "用户令牌" 字段
- 复制那串 token(不是
sk-开头,通常是eyJ…JWT 格式或 40+ 位的 hex) - 回到 VS Code / Cursor → 金沙面板 → 绑定 KEY → 选 "金沙管理 token" → 粘贴
绑定完成后 validateKey() 会调一次 getBalance(),能成功返回即识别为 admin 角色 → 面板显示真实余额和趋势图。
如果你只有 sk- 密钥(拿不到管理 token)怎么办?
会面板会显示:
- ❌ 余额数字显示 "暂不可用"
- ✅ 模型列表 / 切换模型 / 趋势图(基于 mock 历史)仍可正常使用
- ✅ 一个金色按钮 "打开控制台" 直接跳到 jinshaxinxi.cn,按上面 5 步操作即可
给金沙运营的建议
如果想让 sk- 用户也能查自己余额,需要在后端 new-api 配置里打开 "允许 sk token 查询 /api/user/self" 这个开关。这样 probeUserSelf() 端点会从 HTML 错误页变为 JSON 余额数据 —— 不需要改本扩展任何代码,自动就能用。详见 scripts/headless-smoke.ts 探针输出。
实测探针(你可以自己跑 npm run smoke 验证)
--- [4] 端点探针 — 用 raw axios 模拟 JinshaClient 的多端点 fallback ---
✅ 200 /api/pricing 74ms {"auto_groups":["Default"],…}
✅ 200 /api/v1/models 73ms {"data":[{"id":"qwen3.6-plus",…}
✅ 200 /v1/credits 69ms <!doctype html>… ← ❌
✅ 200 /v1/dashboard/billing/credit_grants 67ms <!doctype html>… ← ❌
✅ 200 /api/user/dashboard 69ms {"message":"无权进行此操作…"} ← ❌
✅ 200 /api/user/self 76ms {"message":"无权进行此操作…"} ← ❌
状态码 200 但 body 是 HTML 错误页 = 鉴权失败 → 这种是 new-api 的标准行为,本扩展会继续 fallback 到下一个端点;全部失败就回落到
source: 'unavailable'。
FAQ
Q: 绑定 sk 密钥后为什么面板一直显示"此密钥无法查询余额"?
金沙网关的设计:普通 sk-* 用户密钥只能调用模型,不能查余额。要在控制台登录后获取管理 access token(不是 sk- 开头的那串),用那个 token 才能看到余额和消耗历史。
Q: 模型列表里能看到 gpt-5,为什么切换后调用 503 model_not_found?
金沙是聚合网关,/v1/models 返回的模型是"可见性"(哪些模型存在),但实际能不能调要看背后"渠道(distributor)"是否在线。如果某个渠道挂了,金沙就返回 503 model_not_found: 分组 default 下模型 gpt-5 无可用渠道。
解决办法:选 gpt-5.5-chat-completions 或 qwen3.7-max 等替代模型。
Q: 余额历史能保存多久?
本地最多缓存 720 个点(按轮询间隔 30s 算约 6 小时的高密度数据 + 几次 24h 衰减后的稀疏点)。重启编辑器后历史保留(globalState),但重置扩展会丢失。
Q: 怎么从面板切换到英文?
- 面板右上角的语言切换按钮
- 或
settings.json里"jinshaToken.language": "en-US"
Q: 怎么修改金沙的接口地址(比如私有化部署)?
设置 "jinshaToken.apiBaseUrl" 和 "jinshaToken.pricingUrl",不要在 baseURL 后面再加 /api/v1——代码里的端点路径已自带 /api/ 前缀。
Q: 本地 Mock 服务器怎么用?
只用于开发联调,没真实 KEY 时也能看 UI:
npm run start-mock或npx ts-node scripts/mock-server.ts --port 4000- 设置
"jinshaToken.useMockServer": true - 在面板绑定任意非空字符串作为 KEY 即可
Q: 我的 KEY 安全吗?
KEY 通过 VS Code SecretStorage 存储,macOS 走 Keychain,Windows 走 Credential Vault,Linux 走 libsecret,永不上传任何第三方服务器。所有请求都走 Authorization: Bearer <key> 头,从不写入日志。详见 安全与隐私。
Q: 升级版本后历史数据还在吗?
在的——只要扩展 ID JinShaInc.jinsha-token 不变,globalState 就一直保留。卸载扩展会清掉。
开发与构建
构建命令
| 命令 | 说明 |
|---|---|
npm run build |
一次性生产构建(清空 dist → 并行 build:ext + build:wv) |
npm run watch |
双进程 watch,扩展主进程 + webview 热更新 |
npm run compile |
webpack development 模式单次编译主进程 |
npm run dev:webview |
启动 webview 开发服务器(HMR) |
npm run check-env |
检查 Node / npm 版本与依赖一致性 |
npm run lint |
ESLint 检查 |
npm run smoke |
跑 headless smoke 测试(直连真实金沙 API) |
npm run screenshots |
重生成 6 张 SVG 截图(README / market 用) |
npm run screenshots:png |
生成 SVG + 转 PNG(上传 marketplace 需 PNG) |
npm run clean |
删除 dist/ out/ dist-webview/ |
打包 VSIX
npm install # 确保所有依赖就位
npm run build # 必须先构建
npm run package # 调用 vsce,生成 jinsha-token-<version>.vsix
# 或跳过预构建:
npx vsce package --no-dependencies
💡
vscode:prepublish脚本默认会再跑一次npm run build。如果嫌慢,可以改成空命令:"vscode:prepublish": "echo 'use npm run build explicitly'"💡
postinstall脚本会自动给p-map打补丁,绕过vsce@3.7.x + p-map@5.x在某些 macOS 环境下的 secretlint 并发崩溃 bug。无需手动操作。
验证已生成的 VSIX
# 检查文件类型(应该显示 Zip archive)
file jinsha-token-0.1.0.vsix
# 解压查看
mkdir /tmp/vsix-inspect && unzip jinsha-token-0.1.0.vsix -d /tmp/vsix-inspect
cat /tmp/vsix-inspect/extension/package.json | head -5
# 应能看到 "main": "./dist/extension.js"
发布到 Marketplace
.vsix 文件本身已经是一个合法可安装的扩展包。下面是已经配置好的发布流程(你只需要按步骤执行):
1. 注册 publisher
package.json 里已经写好 publisher: "JinShaInc"。访问 https://marketplace.visualstudio.com/manage → 用 Microsoft 或 GitHub 账号登录 → Create Publisher → 拿到 publisher ID(永久字符串 JinShaInc)。
2. 创建 GitHub 仓库
repository.url 已经指向 https://github.com/yungou168-source/jinsha-token.git,marketplace 会校验这个链接必须可访问。
git init
git remote add origin https://github.com/yungou168-source/jinsha-token.git
git add . && git commit -m "Initial: jinsha-token v0.1.0"
git push -u origin main
3. 创建 Personal Access Token
去 https://dev.azure.com → Personal Access Tokens → New Token,scope 必须包含 Marketplace (Manage)。
4. 登录并发布
# 登录(粘贴 PAT)
npx vsce login JinShaInc
# 发布(自动用 package.json 里的版本号 + publisher)
npx vsce publish
# 或者手动传 PAT
npx vsce publish -p <YOUR_PAT>
第一次发布会被市场审核,1~3 个工作日。
5. Q&A / 截图(提升安装率)
Marketplace 会展示 Q&A section 和 screenshots —— 安装率与展示完整度强相关。
Q&A(在 marketplace 后台 → "Q&A" Tab 手动填):
Q: 用普通 sk- 密钥能看到余额吗?
A: 不能。普通用户密钥只能调用模型;要看余额需要 jinshaxinxi.cn 控制台
的管理 access token(设置 → API 令牌 → 创建)。
Q: 我的 KEY 存哪了?
A: VS Code SecretStorage —— macOS 走 Keychain,Windows 走 Credential Vault,
Linux 走 libsecret。代码里任何 console.log 都不会输出 KEY。
Q: 余额多久刷新一次?
A: 默认 30 秒一次(可在 jinshaToken.pollIntervalSeconds 设置)。
也可点面板右上角"刷新"按钮立即刷新。
Q: 切模型会真的消耗我的额度吗?
A: 不会。本扩展只切换本地偏好 + 帮你打开 jinshaxinxi.cn 的模型页;
实际调用由 Cursor/VS Code 的 AI 插件完成。
Q: 支持哪些模型?
A: 18+ 个 Claude / GPT / GLM / Qwen / DSV4 系列,价格来自
https://jinshaxinxi.cn/api/pricing。
Screenshots(marketplace 后台 → "Detail" Tab 上传,5 张已经准备好):
| 顺序 | 文件 | 描述 |
|---|---|---|
| 1 | resources/screenshots/01-bind.png |
绑定 KEY 弹窗 + 类型选择 |
| 2 | resources/screenshots/02-dashboard.png |
主面板:余额 + 趋势 sparkline + 模型 |
| 3 | resources/screenshots/03-low-balance-warning.png |
余额不足弹窗 + 充值入口 |
| 4 | resources/screenshots/04-models-list.png |
模型列表 + 价格 + 缓存标签 |
| 5 | resources/screenshots/05-toast-success.png |
切换成功 Toast 反馈 |
每张 PNG 已经 1200px 宽(marketplace 建议 1280x800),上传时 marketplace 会自动压缩。
6. Marketplace 合规性(已就绪)
| 检查项 | 状态 | 备注 |
|---|---|---|
package.json 必填字段 |
✅ | name / version / publisher / engines / main / contributes |
publisher 与账户一致 |
✅ | JinShaInc |
repository.url 可访问 |
✅ | https://github.com/yungou168-source/jinsha-token.git |
LICENSE 文件存在 |
✅ | MIT |
无 console.log/error 在生产代码 |
✅ | 全部走 vscode.window.showErrorMessage + OutputChannel |
ESLint no-console 规则 |
✅ | .eslintrc.cjs 已加,PR 会自动 fail |
engines.vscode 已声明 |
✅ | ^1.85.0 |
categories 合理 |
✅ | ["AI", "Other"] |
keywords 丰富 |
✅ | 11 个(jinsha, token, ai, balance, openai, llm…) |
galleryBanner 配 dark theme |
✅ | 黑色背景配金色 icon |
icon ≤ 1 MB |
✅ | 544 KB PNG |
| 5 张截图 | ✅ | 已生成 SVG + PNG 双版本 |
qna 字段指向 issue |
✅ | https://github.com/yungou168-source/jinsha-token/issues |
| 真实 license(不是 "UNLICENSED") | ✅ | MIT |
| 提交前 CI | 即将就绪 | GitHub Actions 在 §下方 |
安全与隐私
- KEY 存储:使用 VS Code
SecretStorageAPI——macOS 走 Keychain,Windows 走 Credential Vault,Linux 走 libsecret。加密 + 系统权限隔离。 - 网络请求:所有 API 请求均通过 HTTPS
Authorization: Bearer <key>头携带 KEY。从不写入日志、状态文件、缓存。 - 历史数据:余额历史点(最多 720 个)仅保存在
globalState(编辑器本地)。不上传任何第三方。 - Mock 服务器:默认关闭(
useMockServer=false)。不会在生产模式下打开任何本地端口。 - 遥测:本扩展不收集任何使用数据,不发送任何分析请求。
发现安全问题请联系 support@jinshaxinxi.cn。
许可证
MIT © 2026 JinSha Inc.





