@yeying-community/web3-bs 1.0.3 → 1.0.5

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 CHANGED
@@ -3,326 +3,19 @@
3
3
  轻量级注入钱包 SDK,专注浏览器端 EIP-1193 Provider。默认优先选择 YeYing Wallet(支持 EIP-6963 多钱包发现)。
4
4
  仅支持浏览器环境(依赖 `window` / `localStorage` / `fetch`)。
5
5
 
6
+ 功能要点:
7
+ - 浏览器端 EIP-1193 Provider 辅助库
8
+ - 默认优先 YeYing Wallet
9
+ - 内置 `signMessage` / `loginWithChallenge` / `refresh` / `logout` 等方法
10
+ - 支持 UCAN Session + SIWE Bridge,用于多后端授权
11
+
6
12
  ## 安装
7
13
 
8
14
  ```bash
9
15
  npm install @yeying-community/web3-bs
10
16
  ```
11
17
 
12
- ## Dapp 集成(浏览器)
13
-
14
- SDK 仅支持浏览器环境。推荐两种接入方式:
15
-
16
- ### 方式一:模块化(打包器 / Vite / Webpack)
17
-
18
- ```ts
19
- import { getProvider, loginWithChallenge, authFetch } from '@yeying-community/web3-bs';
20
-
21
- const provider = await getProvider({ timeoutMs: 3000 });
22
- const login = await loginWithChallenge({
23
- provider,
24
- baseUrl: 'http://localhost:3203/api/v1/public/auth',
25
- storeToken: false,
26
- });
27
-
28
- const res = await authFetch('http://localhost:3203/api/v1/public/profile', { method: 'GET' }, {
29
- baseUrl: 'http://localhost:3203/api/v1/public/auth',
30
- storeToken: false,
31
- });
32
- console.log(await res.json());
33
- ```
34
-
35
- ### 方式二:UMD(纯 HTML)
36
-
37
- ```html
38
- <script src="https://your-host/dist/web3-bs.umd.js"></script>
39
- <script>
40
- const { getProvider, loginWithChallenge } = window.YeYingWeb3;
41
- async function login() {
42
- const provider = await getProvider({ timeoutMs: 3000 });
43
- const result = await loginWithChallenge({
44
- provider,
45
- baseUrl: 'http://localhost:3203/api/v1/public/auth',
46
- storeToken: false,
47
- });
48
- console.log(result);
49
- }
50
- login();
51
- </script>
52
- ```
53
-
54
- 提示:UMD 模式下全局对象为 `window.YeYingWeb3`,需要保证 `dist/web3-bs.umd.js` 可访问。
55
-
56
- ## SIWE 登录(不使用 UCAN)
57
-
58
- 如果只需要传统 SIWE + JWT 登录(单后端),可以不启用 UCAN:
59
-
60
- ```ts
61
- import { getProvider, loginWithChallenge, authFetch, refreshAccessToken, logout } from '@yeying-community/web3-bs';
62
-
63
- const provider = await getProvider();
64
- const login = await loginWithChallenge({
65
- provider,
66
- baseUrl: 'http://localhost:3203/api/v1/public/auth',
67
- storeToken: false,
68
- });
69
-
70
- const profile = await authFetch('http://localhost:3203/api/v1/public/profile', { method: 'GET' }, {
71
- baseUrl: 'http://localhost:3203/api/v1/public/auth',
72
- storeToken: false,
73
- });
74
- console.log(await profile.json());
75
-
76
- await refreshAccessToken({ baseUrl: 'http://localhost:3203/api/v1/public/auth', storeToken: false });
77
- await logout({ baseUrl: 'http://localhost:3203/api/v1/public/auth', storeToken: false });
78
- ```
79
-
80
- ## SIWE 与 UCAN 完整登录流程
81
-
82
- ### SIWE vs UCAN 对比(token 来源 / 有效期 / 续期方式)
83
-
84
- | 维度 | SIWE 登录(JWT) | UCAN 授权 |
85
- | --- | --- | --- |
86
- | Token 来源 | 后端签发 access token + refresh cookie | 前端生成 UCAN(Root/Invocation),后端只校验 |
87
- | 有效期 | access/refresh 由后端配置 | Invocation 默认 5 分钟,Root 默认 24 小时(可配置) |
88
- | 续期方式 | `POST /auth/refresh`(refresh cookie) | 重新生成 Invocation;Root 过期则重新生成 Root + Invocation |
89
-
90
- ### SIWE-only(单后端)
91
- 1. 前端检测钱包 Provider(`getProvider` / `requestAccounts`)。
92
- 2. 请求后端 challenge:`POST /api/v1/public/auth/challenge`。
93
- 3. 钱包签名 challenge(`personal_sign`)。
94
- 4. 提交签名到后端:`POST /api/v1/public/auth/verify`,获取 access token + refresh cookie。
95
- 5. 访问业务接口:`Authorization: Bearer <access-token>`(`authFetch` 会自动附带)。
96
- 6. access 过期时刷新:`POST /api/v1/public/auth/refresh`(依赖 httpOnly refresh cookie)。
97
- 7. 退出登录:`POST /api/v1/public/auth/logout`。
98
-
99
- Mermaid:
100
-
101
- ```mermaid
102
- sequenceDiagram
103
- actor 用户
104
- participant FE as Dapp 前端
105
- participant WP as 钱包 Provider
106
- participant BE as 认证后端
107
-
108
- 用户 ->> FE: 打开 Dapp / 点击登录
109
- FE ->> WP: 获取 Provider / 请求账户
110
- FE ->> BE: POST /auth/challenge { address }
111
- BE -->> FE: 返回 challenge, nonce
112
- FE ->> WP: 签名 challenge
113
- WP -->> FE: 返回 signature
114
- FE ->> BE: POST /auth/verify { address, signature }
115
- BE -->> FE: 返回 access token + refresh cookie
116
- FE ->> BE: GET /public/profile (Authorization: Bearer access)
117
- BE -->> FE: 返回业务数据
118
- FE ->> BE: POST /auth/refresh (refresh cookie)
119
- BE -->> FE: 返回新 access token
120
- FE ->> BE: POST /auth/logout
121
- BE -->> FE: 登出成功
122
- ```
123
-
124
- ### UCAN(多后端 / Delegation)
125
- 1. 前端检测钱包 Provider(`getProvider` / `requestAccounts`)。
126
- 2. 由钱包生成 UCAN Session Key:`createUcanSession`。
127
- 3. 用 SIWE 作为桥梁生成 Root UCAN(包含能力 `[{ resource, action }]`):`createRootUcan` 或 `getOrCreateUcanRoot`。
128
- 4. 针对每个后端生成 Invocation UCAN:`createInvocationUcan({ issuer: session, audience, capabilities, proofs: [root] })`。
129
- 5. 调用后端业务接口:`Authorization: Bearer <UCAN>`(可用 `authUcanFetch`)。
130
- 6. 如需可转授权,先生成 Delegation UCAN:`createDelegationUcan`,由被委任方再生成 Invocation UCAN。
131
- 7. Root/Invocation 过期时重新生成(或由 `initWebDavStorage` 自动处理)。
132
- 提示:Root 过期后前端应重新授权并重试(重新生成 Root + Invocation)。
133
-
134
- 推荐重试逻辑示例:
135
- ```ts
136
- import { getOrCreateUcanRoot, createInvocationUcan } from '@yeying-community/web3-bs';
137
-
138
- async function callWithUcanRetry(target, caps, provider, session) {
139
- const root = await getOrCreateUcanRoot({ provider, session, capabilities: caps });
140
- let token = await createInvocationUcan({
141
- issuer: session,
142
- audience: target.aud,
143
- capabilities: caps,
144
- proofs: [root],
145
- });
146
-
147
- let res = await fetch(target.url, {
148
- headers: { Authorization: `Bearer ${token}` },
149
- });
150
- if (res.status !== 401) return res;
151
-
152
- // Root 过期:重新生成 Root 并重试一次
153
- const newRoot = await getOrCreateUcanRoot({ provider, session, capabilities: caps, expiresInMs: 24 * 60 * 60 * 1000 });
154
- token = await createInvocationUcan({
155
- issuer: session,
156
- audience: target.aud,
157
- capabilities: caps,
158
- proofs: [newRoot],
159
- });
160
- return await fetch(target.url, {
161
- headers: { Authorization: `Bearer ${token}` },
162
- });
163
- }
164
- ```
165
-
166
- Mermaid:
167
-
168
- ```mermaid
169
- sequenceDiagram
170
- actor 用户
171
- participant FE as Dapp 前端
172
- participant WP as 钱包 Provider
173
- participant BA as 后端 A
174
- participant BB as 后端 B
175
-
176
- 用户 ->> FE: 打开 Dapp / 初始化 UCAN
177
- FE ->> WP: createUcanSession
178
- WP -->> FE: 返回 UCAN session key (did, signer)
179
- FE ->> WP: createRootUcan (SIWE 桥接)
180
- WP -->> FE: 返回 Root UCAN (proof)
181
-
182
- FE ->> WP: createInvocationUcan(audience=后端 A)
183
- WP -->> FE: 返回 Invocation UCAN (A)
184
- FE ->> BA: GET /public/profile (Authorization: Bearer UCAN-A)
185
- BA -->> FE: 返回响应
186
-
187
- FE ->> WP: createInvocationUcan(audience=后端 B)
188
- WP -->> FE: 返回 Invocation UCAN (B)
189
- FE ->> BB: GET /public/profile (Authorization: Bearer UCAN-B)
190
- BB -->> FE: 返回响应
191
-
192
- Note over FE,WP: 可选委任链\ncreateDelegationUcan -> 转交 -> createInvocationUcan
193
- ```
194
-
195
- ## 钱包交互 API
196
-
197
- ### Provider 发现
198
- - `getProvider(options?)`
199
- - 自动监听 `eip6963:announceProvider`
200
- - 默认优先 YeYing(`isYeYing` 或 `rdns: io.github.yeying`)
201
-
202
- ### 核心方法
203
- - `requestAccounts({ provider? })`
204
- - `getAccounts(provider?)`
205
- - `getChainId(provider?)`
206
- - `getBalance(provider?, address?, blockTag?)`
207
- - `signMessage({ provider?, message, address?, method? })`
208
- - `method` 默认 `personal_sign`
209
-
210
- ### 事件
211
- - `onAccountsChanged(provider, handler)`
212
- - `onChainChanged(provider, handler)`
213
-
214
- ## 后端交互 API(推荐标准)
215
- OpenAPI 规范:`docs/openapi.yaml`
216
-
217
- ### 响应封装(严格)
218
- 所有响应必须使用以下封装结构:
219
-
220
- ```json
221
- {
222
- "code": 0,
223
- "message": "ok",
224
- "data": { "...": "..." },
225
- "timestamp": 1730000000000
226
- }
227
- ```
228
-
229
- - `code = 0` 表示成功
230
- - `code != 0` 表示失败;`data` 应为 `null`
231
-
232
- ### 1) 获取 Challenge
233
-
234
- `POST /api/v1/public/auth/challenge`
235
-
236
- 请求
237
- ```json
238
- { "address": "0xabc123..." }
239
- ```
240
-
241
- 响应
242
- ```json
243
- {
244
- "code": 0,
245
- "message": "ok",
246
- "data": {
247
- "address": "0xabc123...",
248
- "challenge": "Sign to login...",
249
- "nonce": "random",
250
- "issuedAt": 1730000000000,
251
- "expiresAt": 1730000300000
252
- },
253
- "timestamp": 1730000000000
254
- }
255
- ```
256
-
257
- ### 2) 验证签名
258
-
259
- `POST /api/v1/public/auth/verify`
260
-
261
- 请求
262
- ```json
263
- { "address": "0xabc123...", "signature": "0x..." }
264
- ```
265
-
266
- 响应
267
- ```json
268
- {
269
- "code": 0,
270
- "message": "ok",
271
- "data": {
272
- "address": "0xabc123...",
273
- "token": "access-token",
274
- "expiresAt": 1730086400000,
275
- "refreshExpiresAt": 1730686400000
276
- },
277
- "timestamp": 1730000000000
278
- }
279
- ```
280
-
281
- 说明
282
- - `verify` 应设置 httpOnly 的 `refresh_token` Cookie(用于刷新 access token)。
283
- - 访问受保护接口时,前端使用 `Authorization: Bearer <access-token>`。
284
-
285
- ### 3) 刷新 Access Token
286
-
287
- `POST /api/v1/public/auth/refresh`
288
-
289
- 请求
290
- - 依赖 httpOnly `refresh_token` Cookie
291
-
292
- 响应
293
- ```json
294
- {
295
- "code": 0,
296
- "message": "ok",
297
- "data": {
298
- "address": "0xabc123...",
299
- "token": "new-access-token",
300
- "expiresAt": 1730086400000,
301
- "refreshExpiresAt": 1730686400000
302
- },
303
- "timestamp": 1730000000000
304
- }
305
- ```
306
-
307
- ### 4) 退出登录
308
-
309
- `POST /api/v1/public/auth/logout`
310
-
311
- 响应
312
- ```json
313
- {
314
- "code": 0,
315
- "message": "ok",
316
- "data": { "logout": true },
317
- "timestamp": 1730000000000
318
- }
319
- ```
320
-
321
- ### SDK 绑定
322
- - `loginWithChallenge` 会从 `data.challenge` 读取 challenge,从 `data.token` 读取 token。
323
- - `refreshAccessToken` 调用 `/refresh` 并更新 access token(默认 `credentials: 'include'`)。
324
- - `authFetch` 会自动携带 access token,遇到 401 会尝试刷新再重试一次。
325
- - `logout` 会清理刷新 Cookie 并清空本地 access token(若设置 `storeToken`)。
18
+ 更多集成与流程说明见 `docs/sdk-design.md`。
326
19
 
327
20
  ## 示例
328
21
 
@@ -333,133 +26,49 @@ OpenAPI 规范:`docs/openapi.yaml`
333
26
  - Backend server (Python): `examples/backend/python/app.py`
334
27
  - Backend server (Java): `examples/backend/java/src/main/java/com/yeying/demo/AuthServer.java`
335
28
 
336
- ## UCAN 授权(SIWE Bridge)
29
+ ## 本地验证
337
30
 
338
- SDK 通过 YeYing 钱包生成 UCAN Session Key 并完成签名(由钱包后台隔离私钥)。
339
- Root UCAN 基于 SIWE 签名,
340
- 用于多后端统一鉴权。UCAN `Authorization: Bearer <UCAN>` 发送,后端会验证 UCAN 证明链与能力。
31
+ 1. 构建 SDK:`npm run build`
32
+ 2. 启动后端:`scripts/backend.sh start node`(将 `node` 替换为 `go` / `python` / `java`)
33
+ 3. 启动前端:`python3 -m http.server 8001 --bind 127.0.0.1`
34
+ 4. 访问:`http://127.0.0.1:8001/examples/frontend/dapp.html`
35
+ 5. 确保安装 YeYing 钱包扩展插件
36
+ 6. 点击:`Detect Provider` → `Connect Wallet` → `Login`
341
37
 
342
- 新增 API:
343
- - `createUcanSession(options?)`
344
- - `createRootUcan(options)`
345
- - `createDelegationUcan(options)`
346
- - `createInvocationUcan(options)`
347
- - `authUcanFetch(url, init?, options?)`
38
+ 提示:如果前端来自其他域名,请设置
39
+ `COOKIE_SAMESITE=none` `COOKIE_SECURE=true` 并使用 HTTPS,
40
+ 以便 `refresh_token` Cookie 能随 `credentials: 'include'` 发送。
348
41
 
349
- 示例:
350
- ```ts
351
- const session = await createUcanSession();
352
- const root = await createRootUcan({
353
- provider,
354
- session,
355
- capabilities: [{ resource: 'profile', action: 'read' }],
356
- });
357
-
358
- const ucan = await createInvocationUcan({
359
- issuer: session,
360
- audience: 'did:web:localhost:3203',
361
- capabilities: [{ resource: 'profile', action: 'read' }],
362
- proofs: [root],
363
- });
364
-
365
- const res = await authUcanFetch('http://localhost:3203/api/v1/public/profile', { method: 'GET' }, { ucan });
366
- console.log(await res.json());
367
- ```
42
+ ## 后端脚本用法
368
43
 
369
- 后端默认要求的能力为 `resource=profile`、`action=read`,可通过环境变量覆盖:
370
- - `UCAN_AUD`:服务 DID(默认 `did:web:localhost:3203`)
371
- - `UCAN_RESOURCE`:资源(默认 `profile`)
372
- - `UCAN_ACTION`:动作(默认 `read`)
44
+ 通用格式:
45
+ `./scripts/backend.sh <start|stop|restart|status> <node|go|python|java|all> [--setup] [--no-stop]`
373
46
 
374
- 提示:如需可转授权,使用 `createDelegationUcan` 创建委任链,再用被委任的 Key 生成 Invocation UCAN。
47
+ 示例:
48
+ ```bash
49
+ # 启动 Node 后端
50
+ ./scripts/backend.sh start node
375
51
 
376
- ## WebDAV 存储(Storage)
52
+ # 启动 Go 后端并安装依赖/构建
53
+ ./scripts/backend.sh start go --setup
377
54
 
378
- 提供基于 WebDAV 服务的文件操作封装(上传/下载/删除/目录等),适配 `webdav` 项目 API。
55
+ # 查看全部后端状态
56
+ ./scripts/backend.sh status all
379
57
 
380
- 新增便捷能力:
381
- - `initWebDavStorage`:自动生成/复用 UCAN Invocation Token,并可在首次使用时创建应用目录
382
- - `ensureDirectory(path)`:递归创建目录(存在时自动跳过)
58
+ # 重启 Python 后端
59
+ ./scripts/backend.sh restart python
383
60
 
384
- 示例:
385
- ```ts
386
- import { createWebDavClient, initWebDavStorage, loginWithChallenge } from '@yeying-community/web3-bs';
387
-
388
- const login = await loginWithChallenge({
389
- provider,
390
- baseUrl: 'http://localhost:6065/api/v1/public/auth',
391
- storeToken: false,
392
- });
393
-
394
- const client = createWebDavClient({
395
- baseUrl: 'http://localhost:6065',
396
- token: login.token,
397
- prefix: '/',
398
- });
399
-
400
- const listingXml = await client.listDirectory('/');
401
- await client.upload('/docs/hello.txt', 'Hello WebDAV');
402
- const content = await client.downloadText('/docs/hello.txt');
403
-
404
- // UCAN 登录 + 自动创建应用目录(推荐)
405
- const storage = await initWebDavStorage({
406
- baseUrl: 'http://localhost:6065',
407
- audience: 'did:web:localhost:6065',
408
- appId: 'my-dapp',
409
- capabilities: [{ resource: 'profile', action: 'read' }],
410
- });
411
- await storage.client.upload(`${storage.appDir}/hello.txt`, 'Hello WebDAV');
412
- ```
61
+ # 停止所有后端
62
+ ./scripts/backend.sh stop all
413
63
 
414
- 常用方法:
415
- - `listDirectory(path?, depth?)`(PROPFIND,返回 XML 文本)
416
- - `upload(path, content, contentType?)`
417
- - `download(path)` / `downloadText(path)` / `downloadArrayBuffer(path)`
418
- - `createDirectory(path)`(MKCOL)
419
- - `ensureDirectory(path)`(递归 MKCOL,已存在会跳过)
420
- - `remove(path)`(DELETE)
421
- - `move(path, destination, overwrite?)`
422
- - `copy(path, destination, overwrite?)`
423
- - `getQuota()` / `listRecycle()` / `recoverRecycle(hash)` / `deleteRecycle(hash)` / `clearRecycle()`
424
-
425
- 提示:`capabilities` 需与 WebDAV 后端 UCAN 策略一致;`appId` 默认映射为 `/apps/<appId>`。
426
-
427
- ## Dapp 快速接入(推荐)
428
-
429
- 一次完成 SIWE 登录 + UCAN WebDAV 初始化 + 创建应用目录:
430
-
431
- ```ts
432
- import { initDappSession } from '@yeying-community/web3-bs';
433
-
434
- const session = await initDappSession({
435
- appAuth: {
436
- baseUrl: 'http://localhost:3203/api/v1/public/auth',
437
- storeToken: false,
438
- },
439
- webdav: {
440
- baseUrl: 'http://localhost:6065',
441
- audience: 'did:web:localhost:6065',
442
- appId: 'my-dapp',
443
- capabilities: [{ resource: 'profile', action: 'read' }],
444
- },
445
- });
446
-
447
- const webdav = session.webdavClient;
448
- await webdav?.upload(`${session.webdavAppDir}/hello.txt`, 'Hello WebDAV');
64
+ # 同时启动多个后端(不停止已运行的服务)
65
+ ./scripts/backend.sh start all --no-stop
449
66
  ```
450
67
 
451
- ## 本地验证
452
-
453
- 1. 构建 SDK:`npm run build`
454
- 2. 启动后端:`node examples/backend/node/server.js`
455
- 3. 启动前端:`python3 -m http.server 8001`
456
- 4. 访问:`http://localhost:8001/examples/frontend/dapp.html`
457
- 5. 确保安装 YeYing 钱包扩展插件
458
- 6. 点击:`Detect Provider` → `Connect Wallet` → `Login`
459
-
460
- 提示:如果前端来自其他域名,请设置
461
- `COOKIE_SAMESITE=none` 且 `COOKIE_SECURE=true` 并使用 HTTPS,
462
- 以便 `refresh_token` Cookie 能随 `credentials: 'include'` 发送。
68
+ 说明:
69
+ - 日志位于 `.tmp/backend-logs`
70
+ - 进程 PID 位于 `.tmp/backend-pids`
71
+ - 可通过环境变量传递端口/秘钥/TTL 等配置(如 `PORT`、`JWT_SECRET` 等)
463
72
 
464
73
  ## 多后端联调(不同端口)
465
74
 
@@ -477,8 +86,8 @@ await webdav?.upload(`${session.webdavAppDir}/hello.txt`, 'Hello WebDAV');
477
86
  - Python `3204`
478
87
 
479
88
  前端调用不同端口的后端时:
480
- - 将前端 Origin 加入 `CORS_ORIGINS`(例如 `http://localhost:3203`)
481
- - UCAN 调用的 `audience` 与后端 `UCAN_AUD` 一致(如 `did:web:localhost:3202`)
89
+ - 将前端 Origin 加入 `CORS_ORIGINS`(例如 `http://127.0.0.1:3203`)
90
+ - UCAN 调用的 `audience` 与后端 `UCAN_AUD` 一致(如 `did:web:127.0.0.1:3202`)
482
91
 
483
92
  提示:`examples/frontend/dapp.html` 已内置多后端列表,可在一次 UCAN 授权后依次调用多个服务。
484
93
 
@@ -486,4 +95,27 @@ await webdav?.upload(`${session.webdavAppDir}/hello.txt`, 'Hello WebDAV');
486
95
 
487
96
  ### 刷新token失败
488
97
 
489
- 清理旧 Cookie 后重新登录:在浏览器 DevTools → Application → Cookies → http://localhost:8001 删除 refresh_token,再点 Login 后再点 Refresh Token。
98
+ 清理旧 Cookie 后重新登录:在浏览器 DevTools → Application → Cookies → http://127.0.0.1:8001 删除 refresh_token,再点 Login 后再点 Refresh Token。
99
+
100
+ ### WebDAV 提示 invalid token
101
+
102
+ 报错示例:`authentication failed` / `invalid token`(通常来自 WebDAV 服务端鉴权中间件)。
103
+
104
+ 排查与解决:
105
+ - 确认 `baseUrl` 指向 WebDAV 服务(默认 `http://127.0.0.1:6065`),不要误用 320x 认证后端。
106
+ - `audience` 必须与 WebDAV 服务端 `UCAN_AUD` 一致(例如 `did:web:127.0.0.1:6065`)。
107
+ - `capabilities` 与服务端要求一致(`UCAN_RESOURCE` / `UCAN_ACTION`)。
108
+ - Token 过期或缓存异常时,清理 UCAN 会话并重新登录/生成 Root + Invocation。
109
+
110
+ ### UCAN audience mismatch
111
+
112
+ 日志示例:
113
+ ```
114
+ [2026-01-31T05:19:44.478Z] UCAN profile failed { error: 'UCAN audience mismatch' }
115
+ ```
116
+
117
+ 解决思路:
118
+ - 生成 UCAN 时的 `audience` 必须与目标后端的 `UCAN_AUD` 完全一致。
119
+ - 例如 Node 后端:`did:web:127.0.0.1:3203`
120
+ - 例如 WebDAV 服务:`did:web:127.0.0.1:6065`
121
+ - 多后端联调时,确保每个后端使用对应的 `audience` 生成 Invocation UCAN。
@@ -1,10 +1,12 @@
1
- import { Eip1193Provider, ProviderDiscoveryOptions, ProviderInfo, RequestAccountsOptions } from './types';
1
+ import { Eip1193Provider, ProviderDiscoveryOptions, ProviderInfo, RequestAccountsOptions, AccountSelection, PreferredAccountOptions, WatchAccountsOptions, AccountsChangedHandler } from './types';
2
2
  export declare function isYeYingProvider(provider?: Eip1193Provider | null, info?: ProviderInfo): boolean;
3
3
  export declare function getProvider(options?: ProviderDiscoveryOptions): Promise<Eip1193Provider | null>;
4
4
  export declare function requireProvider(options?: ProviderDiscoveryOptions): Promise<Eip1193Provider>;
5
5
  export declare function requestAccounts(options?: RequestAccountsOptions): Promise<string[]>;
6
6
  export declare function getAccounts(provider?: Eip1193Provider): Promise<string[]>;
7
7
  export declare function getChainId(provider?: Eip1193Provider): Promise<string | null>;
8
+ export declare function getPreferredAccount(options?: PreferredAccountOptions): Promise<AccountSelection>;
9
+ export declare function watchAccounts(provider: Eip1193Provider, handler: AccountsChangedHandler, options?: WatchAccountsOptions): () => void;
8
10
  export declare function getBalance(provider?: Eip1193Provider, address?: string, blockTag?: string): Promise<string>;
9
11
  export declare function onAccountsChanged(provider: Eip1193Provider, handler: (accounts: string[]) => void): () => void;
10
12
  export declare function onChainChanged(provider: Eip1193Provider, handler: (chainId: string) => void): () => void;
@@ -34,6 +34,20 @@ export interface ProviderDiscoveryOptions {
34
34
  export interface RequestAccountsOptions {
35
35
  provider?: Eip1193Provider;
36
36
  }
37
+ export type AccountSelection = {
38
+ account: string | null;
39
+ accounts: string[];
40
+ };
41
+ export interface PreferredAccountOptions extends RequestAccountsOptions {
42
+ storageKey?: string;
43
+ autoConnect?: boolean;
44
+ preferStored?: boolean;
45
+ }
46
+ export interface WatchAccountsOptions {
47
+ storageKey?: string;
48
+ preferStored?: boolean;
49
+ }
50
+ export type AccountsChangedHandler = (payload: AccountSelection) => void;
37
51
  export interface SignMessageOptions {
38
52
  provider?: Eip1193Provider;
39
53
  message: string;
package/dist/dapp.d.ts CHANGED
@@ -8,6 +8,7 @@ export type InitWebDavStorageOptions = {
8
8
  prefix?: string;
9
9
  appDir?: string;
10
10
  appId?: string;
11
+ appAction?: string;
11
12
  ensureAppDir?: boolean;
12
13
  capabilities?: UcanCapability[];
13
14
  invocationCapabilities?: UcanCapability[];