@yeying-community/web3-bs 1.0.14 → 1.0.16
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/dist/auth/encrypt.d.ts +9 -3
- package/dist/auth/ucan.d.ts +28 -0
- package/dist/web3-bs.esm.js +174 -3
- package/dist/web3-bs.esm.js.map +1 -1
- package/dist/web3-bs.umd.js +175 -2
- package/dist/web3-bs.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/auth/encrypt.d.ts
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
* 调用钱包插件的 `yeying_encrypt` / `yeying_decrypt` / `yeying_getCipherSuites`
|
|
5
5
|
* EIP-1193 自定义方法。命名安全套件 + 静默执行 + 站点授权模型同 UCAN。
|
|
6
6
|
*
|
|
7
|
-
*
|
|
7
|
+
* 默认数据密码(password 参数)由 DApp 自行管理与钱包密码独立;
|
|
8
|
+
* 也可通过 passwordSource 请求钱包插件在钱包内部派生加密密码。
|
|
8
9
|
* plaintext 走 base64 字符串跨 message 边界传输。
|
|
9
10
|
*/
|
|
10
11
|
import { isUserRejectedWalletAction } from './provider';
|
|
@@ -14,15 +15,20 @@ export interface CipherSuiteInfo {
|
|
|
14
15
|
description: string;
|
|
15
16
|
mode: 'hash' | 'symmetric';
|
|
16
17
|
}
|
|
18
|
+
export type CipherPasswordSource = 'manual' | 'wallet' | 'wallet+password';
|
|
17
19
|
export interface EncryptOptions {
|
|
18
20
|
data: string | Uint8Array;
|
|
19
|
-
password
|
|
21
|
+
password?: string;
|
|
22
|
+
passwordSource?: CipherPasswordSource;
|
|
23
|
+
passwordContext?: string;
|
|
20
24
|
suite?: string;
|
|
21
25
|
provider?: Eip1193Provider;
|
|
22
26
|
}
|
|
23
27
|
export interface DecryptOptions {
|
|
24
28
|
ciphertext: string;
|
|
25
|
-
password
|
|
29
|
+
password?: string;
|
|
30
|
+
passwordSource?: CipherPasswordSource;
|
|
31
|
+
passwordContext?: string;
|
|
26
32
|
provider?: Eip1193Provider;
|
|
27
33
|
}
|
|
28
34
|
export interface GetCipherSuitesOptions {
|
package/dist/auth/ucan.d.ts
CHANGED
|
@@ -120,6 +120,32 @@ export type UcanAuthErrorInfo = {
|
|
|
120
120
|
status?: number;
|
|
121
121
|
code?: string | number;
|
|
122
122
|
};
|
|
123
|
+
export type ResolveUcanAuthorizationReason = 'missing_root' | 'expired' | 'not_before' | 'missing_account' | 'invalid_issuer' | 'issuer_mismatch' | 'capability_mismatch' | 'audience_mismatch' | 'service_host_mismatch';
|
|
124
|
+
export type ResolveUcanAuthorizationOptions = {
|
|
125
|
+
sessionId?: string;
|
|
126
|
+
root?: UcanRootProof | null;
|
|
127
|
+
currentAccount?: string | null;
|
|
128
|
+
expectedCapabilities?: UcanCapability[];
|
|
129
|
+
expectedAudience?: string | null;
|
|
130
|
+
expectedServiceHosts?: Record<string, string | null | undefined>;
|
|
131
|
+
recoverAccountFromRoot?: boolean;
|
|
132
|
+
nowMs?: number;
|
|
133
|
+
};
|
|
134
|
+
export type ResolveUcanAuthorizationResult = {
|
|
135
|
+
status: 'authorized';
|
|
136
|
+
account: string;
|
|
137
|
+
root: UcanRootProof;
|
|
138
|
+
restoredAccount: boolean;
|
|
139
|
+
expiresAt: number;
|
|
140
|
+
} | {
|
|
141
|
+
status: 'unauthorized';
|
|
142
|
+
reason: ResolveUcanAuthorizationReason;
|
|
143
|
+
root?: UcanRootProof | null;
|
|
144
|
+
account?: string | null;
|
|
145
|
+
expiresAt?: number;
|
|
146
|
+
expected?: string;
|
|
147
|
+
actual?: string;
|
|
148
|
+
};
|
|
123
149
|
export declare const DEFAULT_UCAN_SESSION_TTL_MS: number;
|
|
124
150
|
export declare const DEFAULT_UCAN_TOKEN_TTL_MS: number;
|
|
125
151
|
export declare const DEFAULT_UCAN_TOKEN_SKEW_MS: number;
|
|
@@ -132,6 +158,7 @@ export declare function normalizeUcanCapabilities(caps: UcanCapability[] | undef
|
|
|
132
158
|
includeLegacyAliases?: boolean;
|
|
133
159
|
}): UcanCapability[];
|
|
134
160
|
export declare function normalizeUcanExpiry(exp: number | undefined, fallbackMs: number): number;
|
|
161
|
+
export declare function parseUcanAccountFromIssuer(issuer?: string | null): string | null;
|
|
135
162
|
export declare function decodeUcanPayload(token: string): UcanTokenPayload | null;
|
|
136
163
|
export declare function getUcanTokenTiming(token: string, options?: {
|
|
137
164
|
nowMs?: number;
|
|
@@ -145,6 +172,7 @@ export declare function createUcanSession(options?: CreateUcanSessionOptions): P
|
|
|
145
172
|
export declare function clearUcanSession(id?: string): Promise<void>;
|
|
146
173
|
export declare function storeUcanRoot(root: UcanRootProof, id?: string): Promise<void>;
|
|
147
174
|
export declare function getStoredUcanRoot(id?: string): Promise<UcanRootProof | null>;
|
|
175
|
+
export declare function resolveUcanAuthorization(options?: ResolveUcanAuthorizationOptions): Promise<ResolveUcanAuthorizationResult>;
|
|
148
176
|
export declare function getOrCreateUcanRoot(options: CreateRootUcanOptions): Promise<UcanRootProof>;
|
|
149
177
|
export declare function createRootUcan(options: CreateRootUcanOptions): Promise<UcanRootProof>;
|
|
150
178
|
export declare function createDelegationUcan(options: CreateUcanTokenOptions): Promise<string>;
|
package/dist/web3-bs.esm.js
CHANGED
|
@@ -864,6 +864,73 @@ function normalizeExpiry(exp, fallbackMs) {
|
|
|
864
864
|
function normalizeUcanExpiry(exp, fallbackMs) {
|
|
865
865
|
return normalizeExpiry(exp, fallbackMs);
|
|
866
866
|
}
|
|
867
|
+
function normalizeEthAccount(account) {
|
|
868
|
+
return String(account || '').trim().toLowerCase();
|
|
869
|
+
}
|
|
870
|
+
function parseUcanAccountFromIssuer(issuer) {
|
|
871
|
+
const normalized = String(issuer || '').trim().toLowerCase();
|
|
872
|
+
const prefix = 'did:pkh:eth:';
|
|
873
|
+
if (!normalized.startsWith(prefix))
|
|
874
|
+
return null;
|
|
875
|
+
const account = normalized.slice(prefix.length);
|
|
876
|
+
return account || null;
|
|
877
|
+
}
|
|
878
|
+
function getUcanIssuerForAccount(account) {
|
|
879
|
+
return `did:pkh:eth:${normalizeEthAccount(account)}`;
|
|
880
|
+
}
|
|
881
|
+
function extractUcanStatementPayload(message) {
|
|
882
|
+
if (!message || typeof message !== 'string')
|
|
883
|
+
return null;
|
|
884
|
+
const marker = 'UCAN-AUTH';
|
|
885
|
+
const index = message.indexOf(marker);
|
|
886
|
+
if (index < 0)
|
|
887
|
+
return null;
|
|
888
|
+
const jsonStart = message.indexOf('{', index + marker.length);
|
|
889
|
+
const jsonEnd = message.lastIndexOf('}');
|
|
890
|
+
if (jsonStart < 0 || jsonEnd < jsonStart)
|
|
891
|
+
return null;
|
|
892
|
+
try {
|
|
893
|
+
const parsed = JSON.parse(message.slice(jsonStart, jsonEnd + 1));
|
|
894
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
895
|
+
return null;
|
|
896
|
+
}
|
|
897
|
+
return parsed;
|
|
898
|
+
}
|
|
899
|
+
catch {
|
|
900
|
+
return null;
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
function getUcanRootServiceHosts(root) {
|
|
904
|
+
const payload = extractUcanStatementPayload(root.siwe?.message);
|
|
905
|
+
const hosts = payload?.service_hosts;
|
|
906
|
+
if (!hosts || typeof hosts !== 'object' || Array.isArray(hosts)) {
|
|
907
|
+
return null;
|
|
908
|
+
}
|
|
909
|
+
return hosts;
|
|
910
|
+
}
|
|
911
|
+
function getServiceHostMismatch(root, expectedServiceHosts) {
|
|
912
|
+
if (!expectedServiceHosts)
|
|
913
|
+
return null;
|
|
914
|
+
const entries = Object.entries(expectedServiceHosts)
|
|
915
|
+
.map(([key, value]) => [key, String(value || '').trim()])
|
|
916
|
+
.filter(([, value]) => Boolean(value));
|
|
917
|
+
if (!entries.length)
|
|
918
|
+
return null;
|
|
919
|
+
const hosts = getUcanRootServiceHosts(root);
|
|
920
|
+
if (!hosts) {
|
|
921
|
+
return {
|
|
922
|
+
expected: entries.map(([key, value]) => `${key}:${value}`).join('|'),
|
|
923
|
+
actual: '',
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
for (const [key, expected] of entries) {
|
|
927
|
+
const actual = typeof hosts[key] === 'string' ? hosts[key].trim() : '';
|
|
928
|
+
if (actual !== expected) {
|
|
929
|
+
return { expected, actual };
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
return null;
|
|
933
|
+
}
|
|
867
934
|
function decodeUcanPayload(token) {
|
|
868
935
|
const parts = String(token || '').split('.');
|
|
869
936
|
if (parts.length < 2)
|
|
@@ -1291,6 +1358,105 @@ function capsEqual(a, b) {
|
|
|
1291
1358
|
function isRootExpired(root, nowMs) {
|
|
1292
1359
|
return Boolean(root.exp && nowMs > root.exp);
|
|
1293
1360
|
}
|
|
1361
|
+
async function resolveUcanAuthorization(options = {}) {
|
|
1362
|
+
const root = options.root === undefined
|
|
1363
|
+
? await getStoredUcanRoot(options.sessionId || DEFAULT_SESSION_ID)
|
|
1364
|
+
: options.root;
|
|
1365
|
+
const nowMs = options.nowMs ?? Date.now();
|
|
1366
|
+
if (!root) {
|
|
1367
|
+
return { status: 'unauthorized', reason: 'missing_root', root };
|
|
1368
|
+
}
|
|
1369
|
+
if (typeof root.exp !== 'number' || root.exp <= nowMs) {
|
|
1370
|
+
return {
|
|
1371
|
+
status: 'unauthorized',
|
|
1372
|
+
reason: 'expired',
|
|
1373
|
+
root,
|
|
1374
|
+
expiresAt: root.exp,
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
if (typeof root.nbf === 'number' && root.nbf > nowMs) {
|
|
1378
|
+
return {
|
|
1379
|
+
status: 'unauthorized',
|
|
1380
|
+
reason: 'not_before',
|
|
1381
|
+
root,
|
|
1382
|
+
expiresAt: root.exp,
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
const accountFromIssuer = parseUcanAccountFromIssuer(root.iss);
|
|
1386
|
+
if (!accountFromIssuer) {
|
|
1387
|
+
return {
|
|
1388
|
+
status: 'unauthorized',
|
|
1389
|
+
reason: 'invalid_issuer',
|
|
1390
|
+
root,
|
|
1391
|
+
expiresAt: root.exp,
|
|
1392
|
+
actual: root.iss,
|
|
1393
|
+
};
|
|
1394
|
+
}
|
|
1395
|
+
const currentAccount = normalizeEthAccount(options.currentAccount);
|
|
1396
|
+
if (!currentAccount && !options.recoverAccountFromRoot) {
|
|
1397
|
+
return {
|
|
1398
|
+
status: 'unauthorized',
|
|
1399
|
+
reason: 'missing_account',
|
|
1400
|
+
root,
|
|
1401
|
+
account: null,
|
|
1402
|
+
expiresAt: root.exp,
|
|
1403
|
+
};
|
|
1404
|
+
}
|
|
1405
|
+
const account = currentAccount || accountFromIssuer;
|
|
1406
|
+
const expectedIssuer = getUcanIssuerForAccount(account);
|
|
1407
|
+
if (root.iss !== expectedIssuer) {
|
|
1408
|
+
return {
|
|
1409
|
+
status: 'unauthorized',
|
|
1410
|
+
reason: 'issuer_mismatch',
|
|
1411
|
+
root,
|
|
1412
|
+
account,
|
|
1413
|
+
expiresAt: root.exp,
|
|
1414
|
+
expected: expectedIssuer,
|
|
1415
|
+
actual: root.iss,
|
|
1416
|
+
};
|
|
1417
|
+
}
|
|
1418
|
+
if (options.expectedCapabilities &&
|
|
1419
|
+
!capsEqual(root.cap, options.expectedCapabilities)) {
|
|
1420
|
+
return {
|
|
1421
|
+
status: 'unauthorized',
|
|
1422
|
+
reason: 'capability_mismatch',
|
|
1423
|
+
root,
|
|
1424
|
+
account,
|
|
1425
|
+
expiresAt: root.exp,
|
|
1426
|
+
};
|
|
1427
|
+
}
|
|
1428
|
+
const expectedAudience = String(options.expectedAudience || '').trim();
|
|
1429
|
+
if (expectedAudience && root.aud !== expectedAudience) {
|
|
1430
|
+
return {
|
|
1431
|
+
status: 'unauthorized',
|
|
1432
|
+
reason: 'audience_mismatch',
|
|
1433
|
+
root,
|
|
1434
|
+
account,
|
|
1435
|
+
expiresAt: root.exp,
|
|
1436
|
+
expected: expectedAudience,
|
|
1437
|
+
actual: root.aud,
|
|
1438
|
+
};
|
|
1439
|
+
}
|
|
1440
|
+
const serviceHostMismatch = getServiceHostMismatch(root, options.expectedServiceHosts);
|
|
1441
|
+
if (serviceHostMismatch) {
|
|
1442
|
+
return {
|
|
1443
|
+
status: 'unauthorized',
|
|
1444
|
+
reason: 'service_host_mismatch',
|
|
1445
|
+
root,
|
|
1446
|
+
account,
|
|
1447
|
+
expiresAt: root.exp,
|
|
1448
|
+
expected: serviceHostMismatch.expected,
|
|
1449
|
+
actual: serviceHostMismatch.actual,
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
return {
|
|
1453
|
+
status: 'authorized',
|
|
1454
|
+
account,
|
|
1455
|
+
root,
|
|
1456
|
+
restoredAccount: !currentAccount && account === accountFromIssuer,
|
|
1457
|
+
expiresAt: root.exp,
|
|
1458
|
+
};
|
|
1459
|
+
}
|
|
1294
1460
|
async function getOrCreateUcanRoot(options) {
|
|
1295
1461
|
const provider = options.provider || (await requireProvider());
|
|
1296
1462
|
const session = options.session || (await createUcanSession({ id: options.sessionId, provider }));
|
|
@@ -1870,7 +2036,8 @@ async function authCentralUcanFetch(input, init = {}, options = {}) {
|
|
|
1870
2036
|
* 调用钱包插件的 `yeying_encrypt` / `yeying_decrypt` / `yeying_getCipherSuites`
|
|
1871
2037
|
* EIP-1193 自定义方法。命名安全套件 + 静默执行 + 站点授权模型同 UCAN。
|
|
1872
2038
|
*
|
|
1873
|
-
*
|
|
2039
|
+
* 默认数据密码(password 参数)由 DApp 自行管理与钱包密码独立;
|
|
2040
|
+
* 也可通过 passwordSource 请求钱包插件在钱包内部派生加密密码。
|
|
1874
2041
|
* plaintext 走 base64 字符串跨 message 边界传输。
|
|
1875
2042
|
*/
|
|
1876
2043
|
class CipherError extends Error {
|
|
@@ -1921,6 +2088,8 @@ async function encrypt(options) {
|
|
|
1921
2088
|
params: [{
|
|
1922
2089
|
data: options.data,
|
|
1923
2090
|
password: options.password,
|
|
2091
|
+
passwordSource: options.passwordSource,
|
|
2092
|
+
passwordContext: options.passwordContext,
|
|
1924
2093
|
suite: options.suite
|
|
1925
2094
|
}]
|
|
1926
2095
|
});
|
|
@@ -1944,7 +2113,9 @@ async function decrypt(options) {
|
|
|
1944
2113
|
method: 'yeying_decrypt',
|
|
1945
2114
|
params: [{
|
|
1946
2115
|
ciphertext: options.ciphertext,
|
|
1947
|
-
password: options.password
|
|
2116
|
+
password: options.password,
|
|
2117
|
+
passwordSource: options.passwordSource,
|
|
2118
|
+
passwordContext: options.passwordContext
|
|
1948
2119
|
}]
|
|
1949
2120
|
});
|
|
1950
2121
|
if (!result || typeof result !== 'object' || typeof result.plaintext !== 'string') {
|
|
@@ -2525,5 +2696,5 @@ async function initDappSession(options) {
|
|
|
2525
2696
|
return result;
|
|
2526
2697
|
}
|
|
2527
2698
|
|
|
2528
|
-
export { CipherError, DEFAULT_UCAN_SESSION_TTL_MS, DEFAULT_UCAN_TOKEN_SKEW_MS, DEFAULT_UCAN_TOKEN_TTL_MS, WebDavClient, authCentralUcanFetch, authFetch, authUcanFetch, base64ToBytes, bytesToBase64, classifyUcanAuthError, classifyWalletError, clearAccessToken, clearCentralSessionToken, clearUcanSession, createAndIssueCentralUcan, createCentralSession, createDelegationUcan, createInvocationUcan, createRootUcan, createUcanSession, createWebDavClient, decodeUcanPayload, decrypt, deriveAppIdFromHost, deriveAppIdFromLocation, encrypt, focusPendingApproval, getAccessToken, getAccounts, getBalance, getCapabilityAction, getCapabilityResource, getCentralIssuerInfo, getCentralSessionToken, getChainId, getOrCreateInvocationUcan, getOrCreateUcanRoot, getPreferredAccount, getProvider, getStoredUcanRoot, getSupportedCipherSuites, getUcanSession, getUcanTokenTiming, getWalletErrorCode, getWalletErrorMessage, initDappSession, initWebDavStorage, isUcanTokenFresh, isUserRejectedWalletAction, isWalletReconnectError, isYeYingProvider, issueCentralUcan, loginWithChallenge, logout, normalizeAppHostnameForAppId, normalizeUcanCapabilities, normalizeUcanCapability, normalizeUcanExpiry, onAccountsChanged, onChainChanged, refreshAccessToken, requestAccounts, requireProvider, resolveWalletAccount, setAccessToken, setCentralSessionToken, signMessage, storeUcanRoot, watchAccounts, watchProvider };
|
|
2699
|
+
export { CipherError, DEFAULT_UCAN_SESSION_TTL_MS, DEFAULT_UCAN_TOKEN_SKEW_MS, DEFAULT_UCAN_TOKEN_TTL_MS, WebDavClient, authCentralUcanFetch, authFetch, authUcanFetch, base64ToBytes, bytesToBase64, classifyUcanAuthError, classifyWalletError, clearAccessToken, clearCentralSessionToken, clearUcanSession, createAndIssueCentralUcan, createCentralSession, createDelegationUcan, createInvocationUcan, createRootUcan, createUcanSession, createWebDavClient, decodeUcanPayload, decrypt, deriveAppIdFromHost, deriveAppIdFromLocation, encrypt, focusPendingApproval, getAccessToken, getAccounts, getBalance, getCapabilityAction, getCapabilityResource, getCentralIssuerInfo, getCentralSessionToken, getChainId, getOrCreateInvocationUcan, getOrCreateUcanRoot, getPreferredAccount, getProvider, getStoredUcanRoot, getSupportedCipherSuites, getUcanSession, getUcanTokenTiming, getWalletErrorCode, getWalletErrorMessage, initDappSession, initWebDavStorage, isUcanTokenFresh, isUserRejectedWalletAction, isWalletReconnectError, isYeYingProvider, issueCentralUcan, loginWithChallenge, logout, normalizeAppHostnameForAppId, normalizeUcanCapabilities, normalizeUcanCapability, normalizeUcanExpiry, onAccountsChanged, onChainChanged, parseUcanAccountFromIssuer, refreshAccessToken, requestAccounts, requireProvider, resolveUcanAuthorization, resolveWalletAccount, setAccessToken, setCentralSessionToken, signMessage, storeUcanRoot, watchAccounts, watchProvider };
|
|
2529
2700
|
//# sourceMappingURL=web3-bs.esm.js.map
|