@agentunion/fastaun-browser 0.4.2 → 0.4.4

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +190 -164
  2. package/_packed_docs/0.4.0_/345/267/256/345/274/202/346/240/270/345/256/236/345/206/263/347/255/226/350/256/260/345/275/225.md +302 -0
  3. package/_packed_docs/AUN_SDK_0.4.0_/350/256/276/350/256/241/345/257/271/346/257/224/345/210/206/346/236/220.md +194 -0
  4. package/_packed_docs/AUN_SDK_/351/207/215/346/236/204/345/256/236/346/226/275/350/256/241/345/210/222.md +596 -596
  5. package/_packed_docs/AUN_SDK_/351/207/215/346/236/204/350/256/276/350/256/241/346/226/271/346/241/210_v3.md +1698 -1697
  6. package/_packed_docs/CHANGELOG.md +190 -164
  7. package/_packed_docs/INDEX.md +17 -17
  8. package/_packed_docs/KITE_DOCS_GUIDE.md +11 -11
  9. package/_packed_docs/agent.md/SCHEMA.md +49 -49
  10. package/_packed_docs/agent.md/examples/signed-openclaw-lobster.md +22 -22
  11. package/_packed_docs/agent.md//350/277/234/347/250/213agent.md/347/274/223/345/255/230/344/270/216etag/351/200/217/344/274/240/346/226/271/346/241/210.md +327 -327
  12. package/_packed_docs/cli/AUN-CLI/350/256/276/350/256/241/346/226/207/346/241/243.md +686 -686
  13. package/_packed_docs/design/2026-05-22-aun-rpc-trace-enhancement.md +542 -542
  14. package/_packed_docs/design/E2EE_V2/347/256/200/345/214/226/344/270/2721DH/345/212/240Per-AID_Wrap/346/226/271/346/241/210.md +124 -124
  15. package/_packed_docs/design//350/267/250/350/257/255/350/250/200/345/256/271/345/231/250E2E/346/265/213/350/257/225/346/226/271/346/241/210.md +665 -665
  16. package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +2 -2
  17. package/_packed_docs/protocol/14-/344/272/244/344/272/222/346/234/272/345/210/266-/345/223/215/345/272/224/346/250/241/345/274/217/344/270/216/350/207/252/344/270/273/346/250/241/345/274/217.md +170 -170
  18. package/_packed_docs/protocol/15-/347/246/273/347/272/277/346/216/250/351/200/201/351/200/232/347/237/245/345/215/217/350/256/256.md +419 -419
  19. package/_packed_docs/protocol/README.md +1 -1
  20. package/_packed_docs/protocol/aun-docs-guide.md +1 -1
  21. package/_packed_docs/protocol//351/231/204/345/275/225A-/346/234/257/350/257/255/350/241/250.md +15 -15
  22. package/_packed_docs/protocol//351/231/204/345/275/225B-/346/211/251/345/261/225/346/200/247/346/214/207/345/215/227.md +4 -4
  23. package/_packed_docs/protocol//351/231/204/345/275/225J-/345/256/242/346/210/267/347/253/257/346/216/245/345/205/245/347/244/272/344/276/213.md +98 -98
  24. package/_packed_docs/protocol//351/231/204/345/275/225M-JWT/350/256/244/350/257/201/345/256/236/347/216/260/346/214/207/345/215/227.md +46 -46
  25. package/_packed_docs/protocol//351/231/204/345/275/225N-/345/210/206/345/270/203/345/274/217Trace/345/215/217/350/256/256.md +257 -257
  26. package/_packed_docs/python-sdk-v2-only-changelog.md +189 -189
  27. package/_packed_docs/sdk/01-/345/277/253/351/200/237/345/274/200/345/247/213.md +7 -3
  28. package/_packed_docs/sdk/03-/346/240/270/345/277/203/346/246/202/345/277/265.md +1 -1
  29. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +3 -1
  30. package/_packed_docs/sdk/05-E2EE/345/212/240/345/257/206/351/200/232/344/277/241.md +1 -1
  31. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +63 -15
  32. package/_packed_docs/sdk/09-payload-reference.md +13 -13
  33. package/_packed_docs/sdk/E2EE_V2/346/266/210/346/201/257/351/200/232/344/277/241/346/227/266/345/272/217/345/233/276.md +171 -171
  34. package/_packed_docs/sdk/README.md +5 -5
  35. package/dist/aid-store.d.ts.map +1 -1
  36. package/dist/aid-store.js +5 -6
  37. package/dist/aid-store.js.map +1 -1
  38. package/dist/aid.d.ts +2 -1
  39. package/dist/aid.d.ts.map +1 -1
  40. package/dist/aid.js +7 -6
  41. package/dist/aid.js.map +1 -1
  42. package/dist/auth.d.ts.map +1 -1
  43. package/dist/auth.js +4 -0
  44. package/dist/auth.js.map +1 -1
  45. package/dist/bundle.js +292 -188
  46. package/dist/client.d.ts +13 -17
  47. package/dist/client.d.ts.map +1 -1
  48. package/dist/client.js +275 -190
  49. package/dist/client.js.map +1 -1
  50. package/dist/config.d.ts +4 -7
  51. package/dist/config.d.ts.map +1 -1
  52. package/dist/config.js +18 -1
  53. package/dist/config.js.map +1 -1
  54. package/dist/index.d.ts +1 -1
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/keystore/indexeddb.js +5 -5
  58. package/dist/keystore/indexeddb.js.map +1 -1
  59. package/dist/version.d.ts +1 -1
  60. package/dist/version.js +1 -1
  61. package/package.json +1 -1
@@ -29,7 +29,7 @@ AUN 是 ACP 协议的 2.0 版本,采用 WebSocket + JSON-RPC 2.0 定义 Agent
29
29
  | 文档 | 命名空间 | 内容 |
30
30
  |------|---------|------|
31
31
  | [01-身份与凭证协议-auth.md](01-身份与凭证协议-auth.md) | `auth.*` | AID 创建、两阶段登录、证书生命周期、JWT Token 机制 |
32
- | [03-Gateway-连接模式.md](03-Gateway-连接模式.md) | `auth.connect` | Gateway 模式连接流程、auth.connect 握手、心跳重连 |
32
+ | [03-Gateway-连接模式.md](03-Gateway-连接模式.md) | `auth.connect` | Gateway 模式连接流程、auth.connect 握手、心跳重连 |
33
33
  | [04-Peer-子协议.md](04-Peer-子协议.md) | `peer.*` | 对等认证四步握手、证书链验证、nonce 签名规则 |
34
34
  | [05-Relay-子协议.md](05-Relay-子协议.md) | `relay.*` | 中继注册与转发、透明封装、与 peer.* 的关系 |
35
35
 
@@ -14,7 +14,7 @@ AUN 协议采用**主协议 + 子协议**架构:
14
14
 
15
15
  子协议文档
16
16
  ├── 01-身份与凭证协议-auth.md ← auth.* 方法、JWT Token
17
- ├── 03-Gateway-连接模式.md ← Gateway 模式、auth.connect
17
+ ├── 03-Gateway-连接模式.md ← Gateway 模式、auth.connect
18
18
  ├── 04-Peer-子协议.md ← peer.* 对等认证
19
19
  └── 05-Relay-子协议.md ← relay.* 中继传输
20
20
 
@@ -163,21 +163,21 @@ JWT Header 中的密钥标识,用于指出该 token 是由哪一把签名密
163
163
  - **Event**:服务端主动推送的事件,需要客户端响应
164
164
  - **Notification**:单向通知,不需要响应
165
165
 
166
- ### auth.connect
167
- Gateway 模式的 WebSocket 会话初始化方法。用于提交认证凭证、协商协议版本并建立连接级上下文。
168
-
169
- **参数**:
170
- - `nonce`:Gateway challenge 下发的一次性随机数
171
- - `auth`:认证方式与凭证
172
- - `protocol.min/max`:客户端支持的协议版本范围
173
- - `device.id/type`:设备信息
174
- - `client`:客户端实例信息
175
- - `delivery_mode`:连接级投递语义
176
- - `capabilities`:客户端能力声明
177
-
178
- **说明**:
179
- - `auth.connect` 成功后 Gateway 返回协商后的 `protocol` 与服务端 `capabilities`,连接进入 READY 状态
180
- - 当前 `capabilities` 语义是客户端能力声明和服务端能力公告,不等同于完整双向能力协商
166
+ ### auth.connect
167
+ Gateway 模式的 WebSocket 会话初始化方法。用于提交认证凭证、协商协议版本并建立连接级上下文。
168
+
169
+ **参数**:
170
+ - `nonce`:Gateway challenge 下发的一次性随机数
171
+ - `auth`:认证方式与凭证
172
+ - `protocol.min/max`:客户端支持的协议版本范围
173
+ - `device.id/type`:设备信息
174
+ - `client`:客户端实例信息
175
+ - `delivery_mode`:连接级投递语义
176
+ - `capabilities`:客户端能力声明
177
+
178
+ **说明**:
179
+ - `auth.connect` 成功后 Gateway 返回协商后的 `protocol` 与服务端 `capabilities`,连接进入 READY 状态
180
+ - 当前 `capabilities` 语义是客户端能力声明和服务端能力公告,不等同于完整双向能力协商
181
181
 
182
182
  ### Mode(连接模式)
183
183
  指当前连接采用的接入方式。AUN 主协议定义三种平级 mode:
@@ -2,9 +2,9 @@
2
2
 
3
3
  > **本文档为非规范性内容**:提供 AUN 协议扩展机制的设计原则,不是协议强制要求。
4
4
 
5
- ## B.1 可选命名空间
6
-
7
- 服务端通过 `hello-ok.result.capabilities.namespaces` 公告可用命名空间;客户端侧需要声明的扩展能力通过 `auth.connect.params.capabilities` 扩展:
5
+ ## B.1 可选命名空间
6
+
7
+ 服务端通过 `hello-ok.result.capabilities.namespaces` 公告可用命名空间;客户端侧需要声明的扩展能力通过 `auth.connect.params.capabilities` 扩展:
8
8
 
9
9
  - `group.*`: 群组管理
10
10
  - `storage.*`: 文件存储
@@ -69,7 +69,7 @@ gateway:
69
69
  **核心原则**:
70
70
  1. **向后兼容**:扩展不能破坏现有协议
71
71
  2. **可选实现**:客户端可以选择不实现扩展
72
- 3. **能力声明与公告**:通过 `auth.connect` 声明客户端能力,通过 `hello-ok` 公告服务端能力;需要双向协商的扩展必须单独定义交集规则
72
+ 3. **能力声明与公告**:通过 `auth.connect` 声明客户端能力,通过 `hello-ok` 公告服务端能力;需要双向协商的扩展必须单独定义交集规则
73
73
  4. **文档清晰**:明确标注哪些是核心协议,哪些是扩展
74
74
 
75
75
  **不推荐的扩展**:
@@ -7,40 +7,40 @@
7
7
  ```javascript
8
8
  // 1. 连接 Gateway
9
9
  const ws = new WebSocket('wss://gateway.example.com/aun');
10
- let msgId = 1;
11
- let token = null;
12
- let gatewayNonce = null;
13
- let savedClientNonce = null; // 保存 client_nonce 用于验证 Auth 服务签名
14
- let savedRequestId = null;
15
-
16
- ws.onopen = () => {
17
- // Gateway 会先推送 challenge;收到后再发 auth.* / auth.connect
18
- };
19
-
20
- // 处理响应和事件
21
- ws.onmessage = async (event) => {
22
- const msg = JSON.parse(event.data);
23
-
24
- // challenge:保存 Gateway nonce,然后开始 auth.* 两阶段登录
25
- if (msg.method === 'challenge') {
26
- gatewayNonce = msg.params.nonce;
27
-
28
- // 步骤1:发送 login_aid1(必需字段:aid, cert, request_id, client_nonce)
29
- savedRequestId = `req-${Date.now()}`;
30
- savedClientNonce = crypto.randomUUID();
31
- ws.send(JSON.stringify({
32
- jsonrpc: '2.0',
33
- id: msgId++,
34
- method: 'auth.aid_login1',
35
- params: {
36
- aid: 'alice.aid.pub',
37
- cert: loadCert(), // PEM 格式证书(必需)
38
- request_id: savedRequestId, // 关联两阶段登录(必需)
39
- client_nonce: savedClientNonce // 客户端随机 nonce(必需)
40
- }
41
- }));
42
- return;
43
- }
10
+ let msgId = 1;
11
+ let token = null;
12
+ let gatewayNonce = null;
13
+ let savedClientNonce = null; // 保存 client_nonce 用于验证 Auth 服务签名
14
+ let savedRequestId = null;
15
+
16
+ ws.onopen = () => {
17
+ // Gateway 会先推送 challenge;收到后再发 auth.* / auth.connect
18
+ };
19
+
20
+ // 处理响应和事件
21
+ ws.onmessage = async (event) => {
22
+ const msg = JSON.parse(event.data);
23
+
24
+ // challenge:保存 Gateway nonce,然后开始 auth.* 两阶段登录
25
+ if (msg.method === 'challenge') {
26
+ gatewayNonce = msg.params.nonce;
27
+
28
+ // 步骤1:发送 login_aid1(必需字段:aid, cert, request_id, client_nonce)
29
+ savedRequestId = `req-${Date.now()}`;
30
+ savedClientNonce = crypto.randomUUID();
31
+ ws.send(JSON.stringify({
32
+ jsonrpc: '2.0',
33
+ id: msgId++,
34
+ method: 'auth.aid_login1',
35
+ params: {
36
+ aid: 'alice.aid.pub',
37
+ cert: loadCert(), // PEM 格式证书(必需)
38
+ request_id: savedRequestId, // 关联两阶段登录(必需)
39
+ client_nonce: savedClientNonce // 客户端随机 nonce(必需)
40
+ }
41
+ }));
42
+ return;
43
+ }
44
44
 
45
45
  // login_aid1 响应:返回 nonce + client_nonce_signature + auth_cert
46
46
  if (msg.result && msg.result.nonce && msg.result.client_nonce_signature) {
@@ -70,24 +70,24 @@ ws.onmessage = async (event) => {
70
70
  if (msg.result && msg.result.token && !msg.result.authenticated) {
71
71
  token = msg.result.token;
72
72
 
73
- // 步骤3:用 token 调用 auth.connect 完成 Gateway 模式会话初始化
74
- ws.send(JSON.stringify({
75
- jsonrpc: '2.0',
76
- id: msgId++,
77
- method: 'auth.connect',
78
- params: {
79
- nonce: gatewayNonce,
80
- auth: { method: 'kite_token', token },
81
- protocol: {min: '1.0', max: '1.0'},
82
- device: {id: 'browser-dev-001', type: 'browser'},
83
- client: {name: 'MyApp', version: '1.0.0'},
84
- capabilities: {e2ee: true, group_e2ee: true}
85
- }
86
- }));
87
- }
88
-
89
- // auth.connect 响应(连接已认证)
90
- if (msg.result && msg.result.authenticated) {
73
+ // 步骤3:用 token 调用 auth.connect 完成 Gateway 模式会话初始化
74
+ ws.send(JSON.stringify({
75
+ jsonrpc: '2.0',
76
+ id: msgId++,
77
+ method: 'auth.connect',
78
+ params: {
79
+ nonce: gatewayNonce,
80
+ auth: { method: 'kite_token', token },
81
+ protocol: {min: '1.0', max: '1.0'},
82
+ device: {id: 'browser-dev-001', type: 'browser'},
83
+ client: {name: 'MyApp', version: '1.0.0'},
84
+ capabilities: {e2ee: true, group_e2ee: true}
85
+ }
86
+ }));
87
+ }
88
+
89
+ // auth.connect 响应(连接已认证)
90
+ if (msg.result && msg.result.authenticated) {
91
91
  console.log('Authenticated as:', msg.result.identity.aid);
92
92
 
93
93
  // 现在可以调用所有方法
@@ -133,9 +133,9 @@ ws.send(JSON.stringify({
133
133
  content_type: 'application/pdf'
134
134
  }
135
135
  ]
136
- }
137
- }
138
- }));
136
+ }
137
+ }
138
+ }));
139
139
  ```
140
140
 
141
141
  ### 12.2 Gateway 模式:移动应用完整流程(iOS)
@@ -144,34 +144,34 @@ ws.send(JSON.stringify({
144
144
  // 1. 连接 Gateway
145
145
  var request = URLRequest(url: URL(string: "wss://gateway.example.com/aun")!)
146
146
  let ws = WebSocket(request: request)
147
- var msgId = 1
148
- var token: String?
149
- var gatewayNonce: String?
150
- var savedClientNonce: String?
151
- var savedRequestId: String?
152
-
153
- // 2. 连接成功后,等待 Gateway challenge,再调用 auth.* 获取 token
154
- ws.onConnected = {
155
- // no-op: Gateway 会主动推送 challenge
156
- }
157
-
158
- // 3. 处理响应和事件
159
- ws.onMessage = { message in
160
- if let challenge = message as? ChallengeMessage {
161
- gatewayNonce = challenge.nonce
162
- savedRequestId = UUID().uuidString
163
- savedClientNonce = UUID().uuidString
164
- ws.send(jsonrpc: "2.0", id: msgId, method: "auth.aid_login1",
165
- params: [
166
- "aid": "alice.aid.pub",
167
- "cert": loadCert(), // PEM 格式证书(必需)
168
- "request_id": savedRequestId!, // 关联两阶段登录(必需)
169
- "client_nonce": savedClientNonce! // 客户端随机 nonce(必需)
170
- ])
171
- msgId += 1
172
- return
173
- }
174
-
147
+ var msgId = 1
148
+ var token: String?
149
+ var gatewayNonce: String?
150
+ var savedClientNonce: String?
151
+ var savedRequestId: String?
152
+
153
+ // 2. 连接成功后,等待 Gateway challenge,再调用 auth.* 获取 token
154
+ ws.onConnected = {
155
+ // no-op: Gateway 会主动推送 challenge
156
+ }
157
+
158
+ // 3. 处理响应和事件
159
+ ws.onMessage = { message in
160
+ if let challenge = message as? ChallengeMessage {
161
+ gatewayNonce = challenge.nonce
162
+ savedRequestId = UUID().uuidString
163
+ savedClientNonce = UUID().uuidString
164
+ ws.send(jsonrpc: "2.0", id: msgId, method: "auth.aid_login1",
165
+ params: [
166
+ "aid": "alice.aid.pub",
167
+ "cert": loadCert(), // PEM 格式证书(必需)
168
+ "request_id": savedRequestId!, // 关联两阶段登录(必需)
169
+ "client_nonce": savedClientNonce! // 客户端随机 nonce(必需)
170
+ ])
171
+ msgId += 1
172
+ return
173
+ }
174
+
175
175
  // login_aid1 响应:返回 nonce + client_nonce_signature + auth_cert
176
176
  if let loginResp = message as? LoginAid1Response {
177
177
  // 验证 Auth 服务身份:用 auth_cert 公钥验证 client_nonce_signature
@@ -198,21 +198,21 @@ ws.onMessage = { message in
198
198
  if let loginResp = message as? LoginAid2Response {
199
199
  token = loginResp.token
200
200
 
201
- // 用 token 调用 auth.connect 完成 Gateway 模式会话初始化
202
- let connectParams: [String: Any] = [
203
- "nonce": gatewayNonce!,
204
- "auth": ["method": "kite_token", "token": token!],
205
- "protocol": ["min": "1.0", "max": "1.0"],
206
- "device": ["id": "ios-dev-001", "type": "mobile"],
207
- "client": ["name": "MyApp", "version": "1.0.0"],
208
- "capabilities": ["e2ee": true, "group_e2ee": true]
209
- ]
210
- ws.send(jsonrpc: "2.0", id: msgId, method: "auth.connect", params: connectParams)
211
- msgId += 1
212
- }
213
-
214
- // auth.connect 响应(连接已认证)
215
- if let response = message as? AuthConnectResponse, response.authenticated {
201
+ // 用 token 调用 auth.connect 完成 Gateway 模式会话初始化
202
+ let connectParams: [String: Any] = [
203
+ "nonce": gatewayNonce!,
204
+ "auth": ["method": "kite_token", "token": token!],
205
+ "protocol": ["min": "1.0", "max": "1.0"],
206
+ "device": ["id": "ios-dev-001", "type": "mobile"],
207
+ "client": ["name": "MyApp", "version": "1.0.0"],
208
+ "capabilities": ["e2ee": true, "group_e2ee": true]
209
+ ]
210
+ ws.send(jsonrpc: "2.0", id: msgId, method: "auth.connect", params: connectParams)
211
+ msgId += 1
212
+ }
213
+
214
+ // auth.connect 响应(连接已认证)
215
+ if let response = message as? AuthConnectResponse, response.authenticated {
216
216
  print("Authenticated as: \(response.identity.aid)")
217
217
 
218
218
  // 现在可以调用所有方法
@@ -55,11 +55,11 @@ eyJhbGciOiJFUzM4NCIsInR5cCI6IkpXVCJ9.eyJhaWQiOiJhbGljZS5haWQucHViIiwiaWF0IjoxNzA
55
55
  **所有 AUN 服务端实现**:
56
56
 
57
57
  ```
58
- 1. 服务收到请求(携带 JWT token)
59
-
60
- 2. 提取 token
61
- - WebSocket: 从 `auth.connect.params.auth.token` 中获取
62
- - 连接状态:token 验证后存储在连接上下文
58
+ 1. 服务收到请求(携带 JWT token)
59
+
60
+ 2. 提取 token
61
+ - WebSocket: 从 `auth.connect.params.auth.token` 中获取
62
+ - 连接状态:token 验证后存储在连接上下文
63
63
 
64
64
  3. 解析 token
65
65
  - Base64 解码 Header 和 Payload
@@ -158,47 +158,47 @@ const token = response.token;
158
158
 
159
159
  ### M.3.2 Token 使用示例
160
160
 
161
- Token 统一通过 `auth.connect` 消息传递。每次 WebSocket 连接(包括重连)都必须在收到 Gateway `challenge` 后调用 `auth.connect`:
162
-
163
- ```javascript
164
- function sendAuthConnect(ws, nonce, token) {
165
- ws.send(JSON.stringify({
166
- jsonrpc: '2.0',
167
- id: 1,
168
- method: 'auth.connect',
169
- params: {
170
- nonce,
171
- auth: { method: 'kite_token', token },
172
- protocol: { min: '1.0', max: '1.0' },
173
- device: { id: 'dev-001', type: 'browser' },
174
- client: { name: 'MyApp', version: '1.0.0' },
175
- capabilities: { e2ee: true, group_e2ee: true }
176
- }
177
- }));
178
- }
179
-
180
- // 首次登录:先调用 auth.* 获取 token,再 auth.connect
181
- const ws = new WebSocket('wss://gateway.example.com/aun');
182
- ws.onmessage = async (event) => {
183
- const msg = JSON.parse(event.data);
184
- if (msg.method !== 'challenge') return;
185
-
186
- // 1. 在 auth.connect 之前调用 auth.* 获取 token
187
- const token = await loginFlow(ws); // login_aid1 + login_aid2
188
-
189
- // 2. 用 token 调用 auth.connect 完成会话初始化
190
- sendAuthConnect(ws, msg.params.nonce, token);
191
- };
192
-
193
- // 重连:直接用已有 token 调用 auth.connect
194
- const ws2 = new WebSocket('wss://gateway.example.com/aun');
195
- ws2.onmessage = (event) => {
196
- const msg = JSON.parse(event.data);
197
- if (msg.method === 'challenge') {
198
- sendAuthConnect(ws2, msg.params.nonce, saved_jwt_token);
199
- }
200
- };
201
- ```
161
+ Token 统一通过 `auth.connect` 消息传递。每次 WebSocket 连接(包括重连)都必须在收到 Gateway `challenge` 后调用 `auth.connect`:
162
+
163
+ ```javascript
164
+ function sendAuthConnect(ws, nonce, token) {
165
+ ws.send(JSON.stringify({
166
+ jsonrpc: '2.0',
167
+ id: 1,
168
+ method: 'auth.connect',
169
+ params: {
170
+ nonce,
171
+ auth: { method: 'kite_token', token },
172
+ protocol: { min: '1.0', max: '1.0' },
173
+ device: { id: 'dev-001', type: 'browser' },
174
+ client: { name: 'MyApp', version: '1.0.0' },
175
+ capabilities: { e2ee: true, group_e2ee: true }
176
+ }
177
+ }));
178
+ }
179
+
180
+ // 首次登录:先调用 auth.* 获取 token,再 auth.connect
181
+ const ws = new WebSocket('wss://gateway.example.com/aun');
182
+ ws.onmessage = async (event) => {
183
+ const msg = JSON.parse(event.data);
184
+ if (msg.method !== 'challenge') return;
185
+
186
+ // 1. 在 auth.connect 之前调用 auth.* 获取 token
187
+ const token = await loginFlow(ws); // login_aid1 + login_aid2
188
+
189
+ // 2. 用 token 调用 auth.connect 完成会话初始化
190
+ sendAuthConnect(ws, msg.params.nonce, token);
191
+ };
192
+
193
+ // 重连:直接用已有 token 调用 auth.connect
194
+ const ws2 = new WebSocket('wss://gateway.example.com/aun');
195
+ ws2.onmessage = (event) => {
196
+ const msg = JSON.parse(event.data);
197
+ if (msg.method === 'challenge') {
198
+ sendAuthConnect(ws2, msg.params.nonce, saved_jwt_token);
199
+ }
200
+ };
201
+ ```
202
202
 
203
203
  **优势**:
204
204
  - Token 不出现在 URL、服务器日志和浏览器历史中