@yeying-community/web3-bs 1.0.5 → 1.0.7
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 +113 -77
- package/dist/auth/central.d.ts +77 -0
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/ucan.d.ts +18 -2
- package/dist/dapp.d.ts +8 -0
- package/dist/web3-bs.esm.js +633 -46
- package/dist/web3-bs.esm.js.map +1 -1
- package/dist/web3-bs.umd.js +647 -45
- package/dist/web3-bs.umd.js.map +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
# YeYing
|
|
1
|
+
# YeYing Browser DApp Access SDK
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
`web3-bs` 是浏览器端 DApp 接入 SDK,用于统一封装:
|
|
4
|
+
|
|
5
|
+
- 钱包连接(EIP-1193 / EIP-6963)
|
|
6
|
+
- SIWE challenge 登录与 JWT 鉴权请求
|
|
7
|
+
- UCAN 多后端授权(钱包 UCAN RPC 优先,失败可回退本地 Ed25519 session)
|
|
8
|
+
- 中心化 UCAN 发行服务接入
|
|
9
|
+
- WebDAV 文件访问与应用目录初始化
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
- 浏览器端 EIP-1193 Provider 辅助库
|
|
8
|
-
- 默认优先 YeYing Wallet
|
|
9
|
-
- 内置 `signMessage` / `loginWithChallenge` / `refresh` / `logout` 等方法
|
|
10
|
-
- 支持 UCAN Session + SIWE Bridge,用于多后端授权
|
|
11
|
+
仅支持浏览器环境(依赖 `window` / `localStorage` / `fetch`)。
|
|
11
12
|
|
|
12
13
|
## 安装
|
|
13
14
|
|
|
@@ -15,68 +16,112 @@
|
|
|
15
16
|
npm install @yeying-community/web3-bs
|
|
16
17
|
```
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
## 能力概览
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
### 1) Provider 与账户
|
|
21
22
|
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- Backend server (Python): `examples/backend/python/app.py`
|
|
27
|
-
- Backend server (Java): `examples/backend/java/src/main/java/com/yeying/demo/AuthServer.java`
|
|
23
|
+
- `getProvider` / `requireProvider`
|
|
24
|
+
- `requestAccounts` / `getAccounts` / `getPreferredAccount` / `watchAccounts`
|
|
25
|
+
- `getChainId` / `getBalance`
|
|
26
|
+
- `onAccountsChanged` / `onChainChanged`
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
### 2) SIWE + JWT
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
- `signMessage`
|
|
31
|
+
- `loginWithChallenge`
|
|
32
|
+
- `authFetch`
|
|
33
|
+
- `refreshAccessToken`
|
|
34
|
+
- `logout`
|
|
35
|
+
- `getAccessToken` / `setAccessToken` / `clearAccessToken`
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
`COOKIE_SAMESITE=none` 且 `COOKIE_SECURE=true` 并使用 HTTPS,
|
|
40
|
-
以便 `refresh_token` Cookie 能随 `credentials: 'include'` 发送。
|
|
37
|
+
### 3) UCAN(钱包优先 + 本地回退)
|
|
41
38
|
|
|
42
|
-
|
|
39
|
+
- `createUcanSession` / `getUcanSession`
|
|
40
|
+
- `getOrCreateUcanRoot` / `createRootUcan`
|
|
41
|
+
- `createDelegationUcan` / `createInvocationUcan`
|
|
42
|
+
- `authUcanFetch`
|
|
43
|
+
- `normalizeUcanCapabilities`
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
说明:
|
|
46
|
+
- 能调用 `yeying_ucan_session` / `yeying_ucan_sign` 时,优先用钱包侧 UCAN session 签名。
|
|
47
|
+
- 不支持上述钱包 RPC 时,SDK 会回退到浏览器本地 Ed25519 session(IndexedDB 持久化)。
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
### 4) 中心化 UCAN
|
|
50
|
+
|
|
51
|
+
- `getCentralIssuerInfo`
|
|
52
|
+
- `createCentralSession`
|
|
53
|
+
- `issueCentralUcan`
|
|
54
|
+
- `createAndIssueCentralUcan`
|
|
55
|
+
- `authCentralUcanFetch`
|
|
56
|
+
- `getCentralSessionToken` / `setCentralSessionToken` / `clearCentralSessionToken`
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
./scripts/backend.sh start go --setup
|
|
58
|
+
### 5) WebDAV 与 DApp 会话编排
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
60
|
+
- `createWebDavClient`
|
|
61
|
+
- `initWebDavStorage`(自动生成/复用 WebDAV Invocation UCAN,可自动创建应用目录)
|
|
62
|
+
- `initDappSession`(SIWE 登录 + WebDAV UCAN 初始化)
|
|
63
|
+
- `deriveAppIdFromLocation` / `deriveAppIdFromHost`
|
|
57
64
|
|
|
58
|
-
|
|
59
|
-
./scripts/backend.sh restart python
|
|
65
|
+
## 常见接入方式
|
|
60
66
|
|
|
61
|
-
|
|
62
|
-
./scripts/backend.sh stop all
|
|
67
|
+
### 单后端登录(SIWE + JWT)
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
```ts
|
|
70
|
+
import { loginWithChallenge, authFetch } from '@yeying-community/web3-bs';
|
|
71
|
+
|
|
72
|
+
await loginWithChallenge({
|
|
73
|
+
baseUrl: 'http://localhost:3203/api/v1/public/auth',
|
|
74
|
+
storeToken: false,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const res = await authFetch(
|
|
78
|
+
'http://localhost:3203/api/v1/public/profile',
|
|
79
|
+
{ method: 'GET' },
|
|
80
|
+
{ baseUrl: 'http://localhost:3203/api/v1/public/auth', storeToken: false }
|
|
81
|
+
);
|
|
66
82
|
```
|
|
67
83
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
84
|
+
### 多后端 UCAN + WebDAV
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import { initWebDavStorage, deriveAppIdFromLocation } from '@yeying-community/web3-bs';
|
|
88
|
+
|
|
89
|
+
const appId = deriveAppIdFromLocation(window.location) || 'localhost-8001';
|
|
90
|
+
const webdav = await initWebDavStorage({
|
|
91
|
+
baseUrl: 'http://localhost:6065',
|
|
92
|
+
audience: 'did:web:localhost:6065',
|
|
93
|
+
appId,
|
|
94
|
+
capabilities: [{ with: `app:all:${appId}`, can: 'write' }],
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
await webdav.client.upload(`${webdav.appDir}/hello.txt`, 'Hello WebDAV');
|
|
98
|
+
```
|
|
72
99
|
|
|
73
|
-
##
|
|
100
|
+
## Demo
|
|
74
101
|
|
|
75
|
-
|
|
102
|
+
- 前端 Demo(双 Tab:单后端 SIWE / 多后端 UCAN+WebDAV):
|
|
103
|
+
`examples/frontend/dapp.html`
|
|
104
|
+
- 前端 TS 示例:`examples/frontend/main.ts`
|
|
105
|
+
- 多语言后端示例:
|
|
106
|
+
- Node: `examples/backend/node/server.js`
|
|
107
|
+
- Go: `examples/backend/go/main.go`
|
|
108
|
+
- Java: `examples/backend/java/src/main/java/com/yeying/demo/AuthServer.java`
|
|
109
|
+
- Python: `examples/backend/python/app.py`
|
|
110
|
+
|
|
111
|
+
## 本地联调
|
|
112
|
+
|
|
113
|
+
1. 构建 SDK:`npm run build`
|
|
114
|
+
2. 启动后端(示例):
|
|
115
|
+
`./scripts/backend.sh start nodejs`
|
|
116
|
+
3. 启动前端:
|
|
117
|
+
`python3 -m http.server 8001 --bind 127.0.0.1`
|
|
118
|
+
4. 打开:
|
|
119
|
+
`http://127.0.0.1:8001/examples/frontend/dapp.html`
|
|
120
|
+
|
|
121
|
+
多后端联调:
|
|
76
122
|
|
|
77
123
|
```bash
|
|
78
124
|
./scripts/backend.sh start all
|
|
79
|
-
./scripts/backend.sh start all --setup
|
|
80
125
|
```
|
|
81
126
|
|
|
82
127
|
默认端口:
|
|
@@ -85,37 +130,28 @@ npm install @yeying-community/web3-bs
|
|
|
85
130
|
- Node `3203`
|
|
86
131
|
- Python `3204`
|
|
87
132
|
|
|
88
|
-
|
|
89
|
-
- 将前端 Origin 加入 `CORS_ORIGINS`(例如 `http://127.0.0.1:3203`)
|
|
90
|
-
- UCAN 调用的 `audience` 与后端 `UCAN_AUD` 一致(如 `did:web:127.0.0.1:3202`)
|
|
91
|
-
|
|
92
|
-
提示:`examples/frontend/dapp.html` 已内置多后端列表,可在一次 UCAN 授权后依次调用多个服务。
|
|
93
|
-
|
|
94
|
-
## 常见问题
|
|
95
|
-
|
|
96
|
-
### 刷新token失败
|
|
133
|
+
## CORS 注意事项
|
|
97
134
|
|
|
98
|
-
|
|
135
|
+
若你用 `http://[::]:8001` 打开页面,请确保后端 CORS 白名单包含该 Origin。
|
|
136
|
+
建议统一加入:
|
|
99
137
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
138
|
+
```bash
|
|
139
|
+
CORS_ORIGINS=http://localhost:8001,http://127.0.0.1:8001,http://[::]:8001
|
|
140
|
+
```
|
|
103
141
|
|
|
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。
|
|
142
|
+
## 本地软链接(开发)
|
|
109
143
|
|
|
110
|
-
|
|
144
|
+
将本仓库作为本地依赖链接到你的 DApp:
|
|
111
145
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
146
|
+
```bash
|
|
147
|
+
mkdir -p /path/to/your-dapp/node_modules/@yeying-community
|
|
148
|
+
ln -s /path/to/web3-bs /path/to/your-dapp/node_modules/@yeying-community/web3-bs
|
|
115
149
|
```
|
|
116
150
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
-
|
|
151
|
+
## 文档导航
|
|
152
|
+
|
|
153
|
+
- [文档导航](./docs/文档导航.md)
|
|
154
|
+
- [快速上手](./docs/快速上手.md)
|
|
155
|
+
- [SDK能力](./docs/SDK能力.md)
|
|
156
|
+
- [移动端认证与授权选型指南](./docs/移动端认证与授权选型指南.md)
|
|
157
|
+
- [接口规范(OpenAPI)](./docs/开放接口规范.yaml)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { AuthBaseOptions } from './types';
|
|
2
|
+
import { type UcanCapability } from './ucan';
|
|
3
|
+
export type CentralAuthBaseOptions = AuthBaseOptions & {
|
|
4
|
+
baseUrl?: string;
|
|
5
|
+
issuerPath?: string;
|
|
6
|
+
sessionPath?: string;
|
|
7
|
+
issuePath?: string;
|
|
8
|
+
accessToken?: string | null;
|
|
9
|
+
storeSessionToken?: boolean;
|
|
10
|
+
sessionTokenStorageKey?: string;
|
|
11
|
+
};
|
|
12
|
+
export type CentralIssuerInfo = {
|
|
13
|
+
enabled?: boolean;
|
|
14
|
+
issuerDid?: string;
|
|
15
|
+
defaultAudience?: string;
|
|
16
|
+
defaultCapabilities?: UcanCapability[];
|
|
17
|
+
response: unknown;
|
|
18
|
+
};
|
|
19
|
+
export type CreateCentralSessionOptions = CentralAuthBaseOptions & {
|
|
20
|
+
subject: string;
|
|
21
|
+
sessionTtlMs?: number;
|
|
22
|
+
};
|
|
23
|
+
export type CentralSessionResult = {
|
|
24
|
+
subject: string;
|
|
25
|
+
sessionToken: string;
|
|
26
|
+
expiresAt?: number;
|
|
27
|
+
issuerDid?: string;
|
|
28
|
+
response: unknown;
|
|
29
|
+
};
|
|
30
|
+
export type IssueCentralUcanOptions = CentralAuthBaseOptions & {
|
|
31
|
+
sessionToken?: string | null;
|
|
32
|
+
audience?: string;
|
|
33
|
+
capabilities?: UcanCapability[];
|
|
34
|
+
expiresInMs?: number;
|
|
35
|
+
ttlMs?: number;
|
|
36
|
+
};
|
|
37
|
+
export type CentralUcanIssueResult = {
|
|
38
|
+
ucan: string;
|
|
39
|
+
issuerDid?: string;
|
|
40
|
+
subject?: string;
|
|
41
|
+
audience?: string;
|
|
42
|
+
capabilities?: UcanCapability[];
|
|
43
|
+
exp?: number;
|
|
44
|
+
nbf?: number;
|
|
45
|
+
iat?: number;
|
|
46
|
+
response: unknown;
|
|
47
|
+
};
|
|
48
|
+
export type CreateAndIssueCentralUcanOptions = CentralAuthBaseOptions & {
|
|
49
|
+
subject: string;
|
|
50
|
+
sessionTtlMs?: number;
|
|
51
|
+
audience?: string;
|
|
52
|
+
capabilities?: UcanCapability[];
|
|
53
|
+
expiresInMs?: number;
|
|
54
|
+
ttlMs?: number;
|
|
55
|
+
};
|
|
56
|
+
export type CreateAndIssueCentralUcanResult = {
|
|
57
|
+
session: CentralSessionResult;
|
|
58
|
+
issue: CentralUcanIssueResult;
|
|
59
|
+
};
|
|
60
|
+
export type AuthCentralUcanFetchOptions = CentralAuthBaseOptions & {
|
|
61
|
+
ucan?: string | null;
|
|
62
|
+
sessionToken?: string | null;
|
|
63
|
+
subject?: string;
|
|
64
|
+
sessionTtlMs?: number;
|
|
65
|
+
audience?: string;
|
|
66
|
+
capabilities?: UcanCapability[];
|
|
67
|
+
expiresInMs?: number;
|
|
68
|
+
ttlMs?: number;
|
|
69
|
+
};
|
|
70
|
+
export declare function getCentralSessionToken(options?: CentralAuthBaseOptions): string | null;
|
|
71
|
+
export declare function setCentralSessionToken(token: string | null, options?: CentralAuthBaseOptions): void;
|
|
72
|
+
export declare function clearCentralSessionToken(options?: CentralAuthBaseOptions): void;
|
|
73
|
+
export declare function getCentralIssuerInfo(options?: CentralAuthBaseOptions): Promise<CentralIssuerInfo>;
|
|
74
|
+
export declare function createCentralSession(options: CreateCentralSessionOptions): Promise<CentralSessionResult>;
|
|
75
|
+
export declare function issueCentralUcan(options?: IssueCentralUcanOptions): Promise<CentralUcanIssueResult>;
|
|
76
|
+
export declare function createAndIssueCentralUcan(options: CreateAndIssueCentralUcanOptions): Promise<CreateAndIssueCentralUcanResult>;
|
|
77
|
+
export declare function authCentralUcanFetch(input: RequestInfo | URL, init?: RequestInit, options?: AuthCentralUcanFetchOptions): Promise<Response>;
|
package/dist/auth/index.d.ts
CHANGED
package/dist/auth/ucan.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { Eip1193Provider } from './types';
|
|
2
2
|
export type UcanCapability = {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
with?: string;
|
|
4
|
+
can?: string;
|
|
5
|
+
resource?: string;
|
|
6
|
+
action?: string;
|
|
7
|
+
nb?: unknown;
|
|
5
8
|
};
|
|
6
9
|
export type UcanRootProof = {
|
|
7
10
|
type: 'siwe';
|
|
@@ -24,11 +27,15 @@ export type UcanTokenPayload = {
|
|
|
24
27
|
nbf?: number;
|
|
25
28
|
prf: UcanProof[];
|
|
26
29
|
};
|
|
30
|
+
export type UcanSessionSource = 'wallet' | 'local';
|
|
27
31
|
export type UcanSessionRecord = {
|
|
28
32
|
id: string;
|
|
29
33
|
did: string;
|
|
30
34
|
createdAt: number;
|
|
31
35
|
expiresAt: number | null;
|
|
36
|
+
source?: UcanSessionSource;
|
|
37
|
+
privateKeyJwk?: JsonWebKey;
|
|
38
|
+
publicKeyJwk?: JsonWebKey;
|
|
32
39
|
root?: UcanRootProof;
|
|
33
40
|
};
|
|
34
41
|
export type UcanSessionKey = {
|
|
@@ -36,6 +43,7 @@ export type UcanSessionKey = {
|
|
|
36
43
|
did: string;
|
|
37
44
|
createdAt: number;
|
|
38
45
|
expiresAt: number | null;
|
|
46
|
+
source?: UcanSessionSource;
|
|
39
47
|
signer?: (signingInput: string, payload: UcanTokenPayload) => Promise<string>;
|
|
40
48
|
privateKey?: CryptoKey;
|
|
41
49
|
};
|
|
@@ -81,6 +89,14 @@ export type UcanFetchOptions = {
|
|
|
81
89
|
notBeforeMs?: number;
|
|
82
90
|
fetcher?: typeof fetch;
|
|
83
91
|
};
|
|
92
|
+
export declare function getCapabilityResource(cap: UcanCapability | null | undefined): string;
|
|
93
|
+
export declare function getCapabilityAction(cap: UcanCapability | null | undefined): string;
|
|
94
|
+
export declare function normalizeUcanCapability(cap: UcanCapability | null | undefined, options?: {
|
|
95
|
+
includeLegacyAliases?: boolean;
|
|
96
|
+
}): UcanCapability | null;
|
|
97
|
+
export declare function normalizeUcanCapabilities(caps: UcanCapability[] | undefined, options?: {
|
|
98
|
+
includeLegacyAliases?: boolean;
|
|
99
|
+
}): UcanCapability[];
|
|
84
100
|
export declare function getUcanSession(id?: string, provider?: Eip1193Provider): Promise<UcanSessionKey | null>;
|
|
85
101
|
export declare function createUcanSession(options?: CreateUcanSessionOptions): Promise<UcanSessionKey>;
|
|
86
102
|
export declare function clearUcanSession(id?: string): Promise<void>;
|
package/dist/dapp.d.ts
CHANGED
|
@@ -45,5 +45,13 @@ export type InitDappSessionResult = {
|
|
|
45
45
|
webdavToken?: string;
|
|
46
46
|
webdavAppDir?: string;
|
|
47
47
|
};
|
|
48
|
+
export type AppIdLocationLike = {
|
|
49
|
+
host?: string | null;
|
|
50
|
+
hostname?: string | null;
|
|
51
|
+
port?: string | number | null;
|
|
52
|
+
};
|
|
53
|
+
export declare function normalizeAppHostnameForAppId(hostname: string): string;
|
|
54
|
+
export declare function deriveAppIdFromHost(host: string): string;
|
|
55
|
+
export declare function deriveAppIdFromLocation(locationLike?: AppIdLocationLike): string;
|
|
48
56
|
export declare function initWebDavStorage(options: InitWebDavStorageOptions): Promise<InitWebDavStorageResult>;
|
|
49
57
|
export declare function initDappSession(options: InitDappSessionOptions): Promise<InitDappSessionResult>;
|