unified-keys 0.1.0

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/README.md ADDED
@@ -0,0 +1,87 @@
1
+ # unified-keys
2
+
3
+ 自建通用 API key 管理 SDK。**明文存储 + 明文返回 + 完整使用记录**。服务跑在 Cloudflare Worker + D1,替代 Unkey SaaS。
4
+
5
+ ## 特性
6
+
7
+ - ✅ **明文可重复显示**:list/get 返回完整明文(Unkey 只给前缀)
8
+ - ✅ **完整使用记录**:每次 verify/refund/create/delete 写 usage_log(Unkey 无)
9
+ - ✅ **verify 原子扣减**:`UPDATE ... WHERE credits>0 RETURNING`,并发安全
10
+ - ✅ **多 app 命名空间**:appId(slug)区分项目,首次创建 key 自动注册
11
+ - ✅ **零依赖**:纯 fetch,Worker/Node/Next.js 通用
12
+ - ✅ **TS 强类型**
13
+
14
+ ## 安装
15
+
16
+ ```bash
17
+ pnpm add unified-keys
18
+ ```
19
+
20
+ ## 快速开始
21
+
22
+ ```ts
23
+ import { createClient, verifyKey } from "unified-keys";
24
+
25
+ const client = createClient({
26
+ baseUrl: "https://keys.932324.xyz",
27
+ rootKey: process.env.KEYS_ROOT_KEY,
28
+ });
29
+
30
+ // 创建 key(明文返回)
31
+ const { keys } = await client.createKey({
32
+ appId: "my-app",
33
+ credits: 5,
34
+ externalId: "user-123",
35
+ meta: { plan: "pro" },
36
+ });
37
+ console.log(keys[0].key); // 完整明文
38
+
39
+ // 验证 + 扣减(用户持有 key)
40
+ const result = await verifyKey(
41
+ { baseUrl: "https://keys.932324.xyz" },
42
+ { key: userKey, decrement: true, context: { username: "alice" } }
43
+ );
44
+ ```
45
+
46
+ ## API
47
+
48
+ ### `createClient({ baseUrl, rootKey })` → client
49
+ 管理客户端。`rootKey` 用于管理 API(verify 端点不需要)。
50
+
51
+ ### `client.createKey({ appId, prefix?, credits?, maxUses?, meta?, externalId?, expiresAt?, count? })`
52
+ 创建 key。返回 `{ keys: [{ key, keyId }] }`,`key` 是完整明文。`appId` 首次自动注册。
53
+
54
+ ### `verifyKey({ baseUrl }, { key, decrement?, context? })`
55
+ 公开验证(无需 rootKey)。`decrement: true` 扣减额度并写 verify log;`false` 只查。
56
+ 返回 `{ valid, found, keyId, remaining, maxUses, meta, externalId, appId, enabled, expiresAt, createdAt }`。
57
+
58
+ ### `client.listKeys({ appId, limit?, offset? })`
59
+ 列表,含完整明文。返回 `{ keys: KeyRecord[], total }`。
60
+
61
+ ### `client.getKey(keyId)`
62
+ 详情(明文 + 最近 50 条 usage_logs)。
63
+
64
+ ### `client.getKeyUsageLogs(keyId, { limit? })`
65
+ 使用记录。返回 `{ logs: UsageLog[] }`。
66
+
67
+ ### `client.updateCredits(keyId, { operation, value, context? })`
68
+ 调整额度。`operation: "increment" | "decrement" | "set"`。increment 写 `refund` 事件。
69
+
70
+ ### `client.updateKey(keyId, { meta?, enabled?, expiresAt? })`
71
+ 更新元数据/禁用。
72
+
73
+ ### `client.deleteKey(keyId)` / `client.deleteKeys(keyIds)`
74
+
75
+ ## usage_log event 类型
76
+
77
+ | event | 触发 | creditsBefore/After |
78
+ |---|---|---|
79
+ | `verify` | verify decrement:true 扣减 | ✅ |
80
+ | `refund` | updateCredits increment | ✅ |
81
+ | `create` | createKey | after = 初始额度 |
82
+ | `delete` | deleteKey | — |
83
+ | `update` | updateKey / updateCredits(decrement/set) | — |
84
+
85
+ ## License
86
+
87
+ MIT
package/SKILL.md ADDED
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: unified-keys
3
+ description: 当项目需要管理 API key(创建、验证扣减额度、查询使用记录、管理端显示明文)时使用。自建通用 key 服务 keys.932324.xyz,明文存储 + 完整使用记录,npm 包 unified-keys。
4
+ ---
5
+
6
+ # unified-keys
7
+
8
+ 自建通用 API key 管理 SDK(替代 Unkey)。**明文存储 + 明文返回 + 完整使用记录**。服务跑在 Cloudflare Worker(`keys.932324.xyz`),数据存 D1。
9
+
10
+ ## 何时用
11
+
12
+ - 项目要发 API key / 邀请码 / 访问凭证给用户
13
+ - 需要 verify key + 原子扣减额度(credits)
14
+ - 想看每个 key 的使用历史(谁、何时、扣了几次、退了几次)
15
+ - 想在管理端显示**完整 key 明文**(Unkey 做不到,只给前缀)
16
+ - 多项目共用一个 key 服务(appId 命名空间隔离)
17
+
18
+ ## 安装
19
+
20
+ ```bash
21
+ pnpm add unified-keys
22
+ # 或 npm i unified-keys
23
+ ```
24
+
25
+ ## 服务端点
26
+
27
+ - **公开 verify**:`POST https://keys.932324.xyz/v1/keys/verify`(无需鉴权,任何持有 key 的人可调)
28
+ - **管理 API**:`https://keys.932324.xyz/v1/*`(需 `Authorization: Bearer <ROOT_KEY>`)
29
+ - 健康检查:`GET https://keys.932324.xyz/v1/health`
30
+
31
+ ROOT_KEY 联系服务管理员获取。
32
+
33
+ ## 核心 API
34
+
35
+ ```ts
36
+ import { createClient, verifyKey } from "unified-keys";
37
+
38
+ // 管理客户端(需 rootKey)
39
+ const client = createClient({
40
+ baseUrl: "https://keys.932324.xyz",
41
+ rootKey: process.env.KEYS_ROOT_KEY,
42
+ });
43
+
44
+ // 创建 key(明文返回;appId = 项目 slug,首次自动注册)
45
+ const { keys } = await client.createKey({
46
+ appId: "my-app",
47
+ credits: 5, // 初始剩余次数
48
+ maxUses: 5, // 总额度(0 = 无限)
49
+ externalId: "user-123", // 应用层关联业务实体(可选)
50
+ meta: { plan: "pro" }, // 任意元数据(可选)
51
+ count: 1, // 批量创建数
52
+ });
53
+ // keys[0].key = 完整明文(仅创建时与 list/get 返回),keys[0].keyId
54
+
55
+ // 验证 + 扣减(用户持有明文 key,服务端验证)
56
+ const result = await verifyKey(
57
+ { baseUrl: "https://keys.932324.xyz" },
58
+ { key: userKey, decrement: true, context: { username: "alice", ip: "1.2.3.4" } }
59
+ );
60
+ // { valid, found, keyId, remaining, maxUses, meta, externalId, appId, enabled, expiresAt, createdAt }
61
+ // found=false: key 不存在;valid=false found=true: 存在但禁用/过期/额度耗尽
62
+
63
+ // 列表(含完整明文 ★ 区别于 Unkey)
64
+ const { keys: all, total } = await client.listKeys({ appId: "my-app", limit: 200 });
65
+
66
+ // 详情(明文 + 使用记录)
67
+ const { key, usageLogs } = await client.getKey(keyId);
68
+
69
+ // 查使用记录(核心特性)
70
+ const { logs } = await client.getKeyUsageLogs(keyId, { limit: 50 });
71
+ // logs: [{ event: "verify"|"refund"|"create"|"delete"|"update", creditsBefore, creditsAfter, context, createdAt }]
72
+
73
+ // 调整额度(refund 恢复)
74
+ await client.updateCredits(keyId, {
75
+ operation: "increment", // increment | decrement | set
76
+ value: 1,
77
+ context: { reason: "refund" },
78
+ });
79
+
80
+ // 更新元数据 / 禁用
81
+ await client.updateKey(keyId, { meta: { plan: "enterprise" }, enabled: false });
82
+
83
+ // 删除
84
+ await client.deleteKey(keyId);
85
+ await client.deleteKeys([keyId1, keyId2]);
86
+ ```
87
+
88
+ ## 特性(区别于 Unkey)
89
+
90
+ | | unified-keys | Unkey |
91
+ |---|---|---|
92
+ | 明文显示 | ✅ 列表/详情返回完整明文 | ❌ 只给 start 前缀 |
93
+ | 使用记录 | ✅ 每次 verify/refund/create/delete 写 usage_log | ❌ 只给当前 remaining |
94
+ | verify 延迟 | <5ms(D1 binding 零网络跳) | 50-100ms(公网) |
95
+ | 自托管 | ✅ 自己的 D1 | ❌ SaaS |
96
+ | 原子扣减 | ✅ `UPDATE ... WHERE credits>0 RETURNING` | ✅ |
97
+
98
+ ## event 类型(usage_log)
99
+
100
+ - `verify`:verify 扣减(含 creditsBefore/After + context)
101
+ - `refund`:updateCredits increment 恢复额度
102
+ - `create` / `delete` / `update` / `disable`
103
+
104
+ ## 集成示例
105
+
106
+ ### Next.js Route Handler(服务端 verify 用户持有 key)
107
+ ```ts
108
+ import { verifyKey } from "unified-keys";
109
+ export async function POST(req: Request) {
110
+ const { key } = await req.json();
111
+ const r = await verifyKey(
112
+ { baseUrl: "https://keys.932324.xyz" },
113
+ { key, decrement: true, context: { ip: req.headers.get("x-forwarded-for") } }
114
+ );
115
+ if (!r.valid) return Response.json({ error: "invalid key" }, { status: 403 });
116
+ // ... 授权逻辑
117
+ }
118
+ ```
119
+
120
+ ### Next.js Server Component(只读查询,不扣减)
121
+ ```ts
122
+ import { verifyKey } from "unified-keys";
123
+ const info = await verifyKey(
124
+ { baseUrl: "https://keys.932324.xyz" },
125
+ { key: params.key, decrement: false }
126
+ );
127
+ if (!info.found || !info.valid) notFound();
128
+ // info.remaining / info.meta / info.expiresAt
129
+ ```
130
+
131
+ ### Cloudflare Worker(管理端)
132
+ ```ts
133
+ import { createClient } from "unified-keys";
134
+ const client = createClient({
135
+ baseUrl: c.env.KEY_SERVICE_URL,
136
+ rootKey: c.env.KEY_SERVICE_ROOT_KEY,
137
+ });
138
+ await client.createKey({ appId: "my-app", credits: 1 });
139
+ ```
140
+
141
+ ## 实现位置(本项目内)
142
+
143
+ - 服务端:`apps/key-service`(Hono Worker → keys.932324.xyz)
144
+ - SDK:`packages/keys`(发布名 unified-keys)
145
+ - schema:`packages/db/src/schemas/key-service.ts`(key_apps / key_records / key_usage_logs)
146
+ - 已迁移:github-inviter / user-dashboard(shadcn-proxy / notify-me 仍用 Unkey,待后续)
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "unified-keys",
3
+ "version": "0.1.0",
4
+ "description": "自建通用 API key 管理 SDK(明文存储 + 明文返回 + 完整使用记录),调用 keys.932324.xyz 服务",
5
+ "type": "module",
6
+ "main": "./src/index.ts",
7
+ "types": "./src/index.ts",
8
+ "exports": {
9
+ ".": "./src/index.ts",
10
+ "./*": "./src/*.ts"
11
+ },
12
+ "files": [
13
+ "src",
14
+ "README.md",
15
+ "SKILL.md"
16
+ ],
17
+ "keywords": [
18
+ "api-key",
19
+ "key-management",
20
+ "unkey",
21
+ "credits",
22
+ "usage-logs",
23
+ "cloudflare-workers",
24
+ "d1"
25
+ ],
26
+ "license": "MIT",
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "devDependencies": {
31
+ "typescript": "catalog:"
32
+ },
33
+ "scripts": {
34
+ "check-types": "tsc --noEmit"
35
+ }
36
+ }
package/src/client.ts ADDED
@@ -0,0 +1,147 @@
1
+ import type {
2
+ BatchDeleteResult,
3
+ CreateAppInput,
4
+ CreateAppResult,
5
+ CreateKeyInput,
6
+ CreateKeyResult,
7
+ DeleteResult,
8
+ GetKeyResult,
9
+ GetKeyUsageLogsInput,
10
+ KeyServiceClient,
11
+ KeyServiceClientConfig,
12
+ ListAppsResult,
13
+ ListKeysInput,
14
+ ListKeysResult,
15
+ UpdateCreditsInput,
16
+ UpdateCreditsResult,
17
+ UpdateKeyInput,
18
+ UsageLogsResult,
19
+ VerifyInput,
20
+ VerifyResult,
21
+ } from "./types";
22
+
23
+ const KEY_FORMAT = /^[a-zA-Z0-9_-]{8,128}$/;
24
+
25
+ /**
26
+ * key 格式校验(base62 + 下划线/连字符,8-128 位,含可选前缀)。
27
+ * verify 前置校验:格式不对直接判 invalid,不查 DB,省时间。
28
+ */
29
+ export function isValidKeyFormat(key: string): boolean {
30
+ return typeof key === "string" && KEY_FORMAT.test(key);
31
+ }
32
+
33
+ export function createClient(config: KeyServiceClientConfig): KeyServiceClient {
34
+ const baseUrl = config.baseUrl.replace(/\/$/, "");
35
+ const rootKey = config.rootKey;
36
+
37
+ async function request<T>(
38
+ method: string,
39
+ path: string,
40
+ options?: { body?: unknown; auth?: boolean }
41
+ ): Promise<T> {
42
+ const headers: Record<string, string> = {
43
+ "Content-Type": "application/json",
44
+ };
45
+ const needAuth = options?.auth ?? true;
46
+ if (needAuth) {
47
+ if (!rootKey) {
48
+ throw new Error("unified-keys: rootKey is required for management API");
49
+ }
50
+ headers.Authorization = `Bearer ${rootKey}`;
51
+ }
52
+ const res = await fetch(`${baseUrl}${path}`, {
53
+ method,
54
+ headers,
55
+ body: options?.body ? JSON.stringify(options.body) : undefined,
56
+ });
57
+ const text = await res.text();
58
+ let data: unknown;
59
+ try {
60
+ data = text ? JSON.parse(text) : {};
61
+ } catch {
62
+ throw new Error(
63
+ `unified-keys ${method} ${path}: ${res.status} ${text.slice(0, 200)}`
64
+ );
65
+ }
66
+ if (!res.ok) {
67
+ const msg = (data as { error?: string }).error ?? `${res.status}`;
68
+ throw new Error(`unified-keys ${method} ${path}: ${msg}`);
69
+ }
70
+ return data as T;
71
+ }
72
+
73
+ return {
74
+ createApp: (input: CreateAppInput) =>
75
+ request<CreateAppResult>("POST", "/v1/apps", { body: input }),
76
+ listApps: () => request<ListAppsResult>("GET", "/v1/apps"),
77
+ createKey: (input: CreateKeyInput) =>
78
+ request<CreateKeyResult>("POST", "/v1/keys", { body: input }),
79
+ listKeys: (input: ListKeysInput) => {
80
+ const params = new URLSearchParams({ appId: input.appId });
81
+ if (input.limit != null) params.set("limit", String(input.limit));
82
+ if (input.offset != null) params.set("offset", String(input.offset));
83
+ return request<ListKeysResult>("GET", `/v1/keys?${params}`);
84
+ },
85
+ getKey: (keyId: string) =>
86
+ request<GetKeyResult>("GET", `/v1/keys/${keyId}`),
87
+ deleteKey: (keyId: string) =>
88
+ request<DeleteResult>("DELETE", `/v1/keys/${keyId}`),
89
+ deleteKeys: (keyIds: string[]) =>
90
+ request<BatchDeleteResult>("POST", "/v1/keys/batch-delete", {
91
+ body: { keyIds },
92
+ }),
93
+ updateKey: (keyId: string, input: UpdateKeyInput) =>
94
+ request<DeleteResult>("PATCH", `/v1/keys/${keyId}`, {
95
+ body: input,
96
+ }),
97
+ updateCredits: (keyId: string, input: UpdateCreditsInput) =>
98
+ request<UpdateCreditsResult>("POST", `/v1/keys/${keyId}/credits`, {
99
+ body: input,
100
+ }),
101
+ getKeyUsageLogs: (keyId: string, input?: GetKeyUsageLogsInput) => {
102
+ const limit = input?.limit ?? 50;
103
+ return request<UsageLogsResult>(
104
+ "GET",
105
+ `/v1/keys/${keyId}/usage-logs?limit=${limit}`
106
+ );
107
+ },
108
+ verifyKey: (input: VerifyInput) => {
109
+ if (!isValidKeyFormat(input.key)) {
110
+ return Promise.resolve({ valid: false, found: false } as VerifyResult);
111
+ }
112
+ return request<VerifyResult>("POST", "/v1/keys/verify", {
113
+ body: input,
114
+ auth: false,
115
+ });
116
+ },
117
+ };
118
+ }
119
+
120
+ /**
121
+ * 公开 verify 端点,无需 rootKey。
122
+ * 适合「用户持有明文 key、服务端验证并扣减」的场景。
123
+ */
124
+ export async function verifyKey(
125
+ config: { baseUrl: string },
126
+ input: VerifyInput
127
+ ): Promise<VerifyResult> {
128
+ if (!isValidKeyFormat(input.key)) return { valid: false, found: false };
129
+ const baseUrl = config.baseUrl.replace(/\/$/, "");
130
+ const res = await fetch(`${baseUrl}/v1/keys/verify`, {
131
+ method: "POST",
132
+ headers: { "Content-Type": "application/json" },
133
+ body: JSON.stringify(input),
134
+ });
135
+ const text = await res.text();
136
+ let data: unknown;
137
+ try {
138
+ data = text ? JSON.parse(text) : {};
139
+ } catch {
140
+ throw new Error(`unified-keys verify: ${res.status} ${text.slice(0, 200)}`);
141
+ }
142
+ if (!res.ok) {
143
+ const msg = (data as { error?: string }).error ?? `${res.status}`;
144
+ throw new Error(`unified-keys verify: ${msg}`);
145
+ }
146
+ return data as VerifyResult;
147
+ }
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ export { createClient, isValidKeyFormat, verifyKey } from "./client";
2
+ export type {
3
+ AppRecord,
4
+ BatchDeleteResult,
5
+ CreateAppInput,
6
+ CreateAppResult,
7
+ CreatedKey,
8
+ CreateKeyInput,
9
+ CreateKeyResult,
10
+ DeleteResult,
11
+ GetKeyResult,
12
+ GetKeyUsageLogsInput,
13
+ KeyRecord,
14
+ KeyServiceClient,
15
+ KeyServiceClientConfig,
16
+ ListAppsResult,
17
+ ListKeysInput,
18
+ ListKeysResult,
19
+ UpdateCreditsInput,
20
+ UpdateCreditsResult,
21
+ UpdateKeyInput,
22
+ UsageLog,
23
+ UsageLogsResult,
24
+ VerifyInput,
25
+ VerifyResult,
26
+ } from "./types";
package/src/types.ts ADDED
@@ -0,0 +1,175 @@
1
+ /** unified-keys SDK 类型定义 */
2
+
3
+ export interface KeyServiceClientConfig {
4
+ /** 服务端点,如 https://keys.932324.xyz */
5
+ baseUrl: string;
6
+ /** 管理 API 需要;verify 端点不需要 */
7
+ rootKey?: string;
8
+ }
9
+
10
+ export interface AppRecord {
11
+ createdAt: string;
12
+ id: string;
13
+ slug: string;
14
+ }
15
+
16
+ export interface CreateAppInput {
17
+ slug: string;
18
+ }
19
+
20
+ export interface CreateAppResult {
21
+ app: AppRecord;
22
+ }
23
+
24
+ export interface ListAppsResult {
25
+ apps: AppRecord[];
26
+ }
27
+
28
+ export interface CreateKeyInput {
29
+ appId: string;
30
+ /** 批量创建数量,默认 1 */
31
+ count?: number;
32
+ /** 初始额度(剩余次数),默认 1 */
33
+ credits?: number;
34
+ /** ISO 时间字符串,过期时间 */
35
+ expiresAt?: string;
36
+ /** 应用层关联业务实体(如 github-inviter 的 configSlug) */
37
+ externalId?: string;
38
+ /** 总额度(0=无限),默认等于 credits */
39
+ maxUses?: number;
40
+ /** 应用层任意元数据 */
41
+ meta?: Record<string, unknown>;
42
+ /** 可选前缀,生成 `<prefix>_<rand>`;不传则纯 random */
43
+ prefix?: string;
44
+ }
45
+
46
+ export interface CreatedKey {
47
+ /** 完整明文 key(仅创建时与服务端 list/get 返回) */
48
+ key: string;
49
+ keyId: string;
50
+ }
51
+
52
+ export interface CreateKeyResult {
53
+ keys: CreatedKey[];
54
+ }
55
+
56
+ export interface KeyRecord {
57
+ appId: string;
58
+ createdAt: string;
59
+ creditsRemaining: number;
60
+ enabled: boolean;
61
+ expiresAt: string | null;
62
+ externalId: string | null;
63
+ keyId: string;
64
+ maxUses: number;
65
+ meta: Record<string, unknown> | null;
66
+ plaintext: string;
67
+ prefix: string | null;
68
+ updatedAt: string;
69
+ }
70
+
71
+ export interface ListKeysInput {
72
+ appId: string;
73
+ limit?: number;
74
+ offset?: number;
75
+ }
76
+
77
+ export interface ListKeysResult {
78
+ keys: KeyRecord[];
79
+ total: number;
80
+ }
81
+
82
+ export interface UpdateKeyInput {
83
+ enabled?: boolean;
84
+ expiresAt?: string | null;
85
+ meta?: Record<string, unknown>;
86
+ }
87
+
88
+ export interface UpdateCreditsInput {
89
+ /** 上下文,写入 usage_log(如 {reason:"revoke"}) */
90
+ context?: Record<string, unknown>;
91
+ operation: "increment" | "decrement" | "set";
92
+ value: number;
93
+ }
94
+
95
+ export interface UpdateCreditsResult {
96
+ remaining: number;
97
+ }
98
+
99
+ export interface UsageLog {
100
+ appId: string;
101
+ context: Record<string, unknown> | null;
102
+ createdAt: string;
103
+ creditsAfter: number | null;
104
+ creditsBefore: number | null;
105
+ /** verify(扣减) / refund(恢复) / create / delete / update / disable */
106
+ event: string;
107
+ id: string;
108
+ keyId: string;
109
+ }
110
+
111
+ export interface GetKeyUsageLogsInput {
112
+ limit?: number;
113
+ }
114
+
115
+ export interface UsageLogsResult {
116
+ logs: UsageLog[];
117
+ }
118
+
119
+ export interface GetKeyResult {
120
+ key: KeyRecord;
121
+ usageLogs: UsageLog[];
122
+ }
123
+
124
+ export interface VerifyInput {
125
+ /** 上下文,写入 usage_log(如 {username, source, ip}) */
126
+ context?: Record<string, unknown>;
127
+ /** 默认 true;false 时只查不扣(写 verify log 但不扣减) */
128
+ decrement?: boolean;
129
+ /** 完整明文 key */
130
+ key: string;
131
+ }
132
+
133
+ export interface VerifyResult {
134
+ appId?: string;
135
+ createdAt?: string;
136
+ enabled?: boolean;
137
+ expiresAt?: string | null;
138
+ externalId?: string | null;
139
+ /** key 是否存在(区别「不存在」与「存在但额度耗尽」) */
140
+ found: boolean;
141
+ keyId?: string;
142
+ maxUses?: number;
143
+ meta?: Record<string, unknown> | null;
144
+ remaining?: number;
145
+ valid: boolean;
146
+ }
147
+
148
+ export interface DeleteResult {
149
+ success: boolean;
150
+ }
151
+
152
+ export interface BatchDeleteResult {
153
+ deleted: string[];
154
+ failed: string[];
155
+ }
156
+
157
+ export interface KeyServiceClient {
158
+ createApp(input: CreateAppInput): Promise<CreateAppResult>;
159
+ createKey(input: CreateKeyInput): Promise<CreateKeyResult>;
160
+ deleteKey(keyId: string): Promise<DeleteResult>;
161
+ deleteKeys(keyIds: string[]): Promise<BatchDeleteResult>;
162
+ getKey(keyId: string): Promise<GetKeyResult>;
163
+ getKeyUsageLogs(
164
+ keyId: string,
165
+ input?: GetKeyUsageLogsInput
166
+ ): Promise<UsageLogsResult>;
167
+ listApps(): Promise<ListAppsResult>;
168
+ listKeys(input: ListKeysInput): Promise<ListKeysResult>;
169
+ updateCredits(
170
+ keyId: string,
171
+ input: UpdateCreditsInput
172
+ ): Promise<UpdateCreditsResult>;
173
+ updateKey(keyId: string, input: UpdateKeyInput): Promise<DeleteResult>;
174
+ verifyKey(input: VerifyInput): Promise<VerifyResult>;
175
+ }