@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.
@@ -1,10 +1,42 @@
1
1
  const YEYING_RDNS = 'io.github.yeying';
2
2
  const DEFAULT_TIMEOUT = 1000;
3
+ const DEFAULT_ACCOUNT_STORAGE_KEY = 'yeying:last_account';
3
4
  function getWindowEthereum() {
4
5
  if (typeof window === 'undefined')
5
6
  return null;
6
7
  return window.ethereum || null;
7
8
  }
9
+ function readStoredAccount(storageKey) {
10
+ if (typeof localStorage === 'undefined')
11
+ return null;
12
+ try {
13
+ return localStorage.getItem(storageKey);
14
+ }
15
+ catch {
16
+ return null;
17
+ }
18
+ }
19
+ function writeStoredAccount(storageKey, account) {
20
+ if (typeof localStorage === 'undefined')
21
+ return;
22
+ try {
23
+ if (account) {
24
+ localStorage.setItem(storageKey, account);
25
+ }
26
+ else {
27
+ localStorage.removeItem(storageKey);
28
+ }
29
+ }
30
+ catch {
31
+ // ignore storage errors
32
+ }
33
+ }
34
+ function selectPreferredAccount(accounts, stored, preferStored) {
35
+ if (preferStored && stored && accounts.includes(stored)) {
36
+ return stored;
37
+ }
38
+ return accounts[0] || null;
39
+ }
8
40
  function isYeYingProvider(provider, info) {
9
41
  if (!provider)
10
42
  return false;
@@ -110,6 +142,29 @@ async function getChainId(provider) {
110
142
  const chainId = (await p.request({ method: 'eth_chainId' }));
111
143
  return typeof chainId === 'string' ? chainId : null;
112
144
  }
145
+ async function getPreferredAccount(options = {}) {
146
+ const provider = options.provider || (await requireProvider());
147
+ const storageKey = options.storageKey || DEFAULT_ACCOUNT_STORAGE_KEY;
148
+ const preferStored = options.preferStored !== false;
149
+ let accounts = await getAccounts(provider);
150
+ if (accounts.length === 0 && options.autoConnect) {
151
+ accounts = await requestAccounts({ provider });
152
+ }
153
+ const stored = readStoredAccount(storageKey);
154
+ const account = selectPreferredAccount(accounts, stored, preferStored);
155
+ writeStoredAccount(storageKey, account);
156
+ return { account, accounts };
157
+ }
158
+ function watchAccounts(provider, handler, options = {}) {
159
+ const storageKey = options.storageKey || DEFAULT_ACCOUNT_STORAGE_KEY;
160
+ const preferStored = options.preferStored !== false;
161
+ return onAccountsChanged(provider, (accounts) => {
162
+ const stored = readStoredAccount(storageKey);
163
+ const account = selectPreferredAccount(accounts, stored, preferStored);
164
+ writeStoredAccount(storageKey, account);
165
+ handler({ account, accounts });
166
+ });
167
+ }
113
168
  async function getBalance(provider, address, blockTag = 'latest') {
114
169
  const p = provider || (await requireProvider());
115
170
  let target = address;
@@ -708,8 +763,8 @@ async function createRootUcan(options) {
708
763
  const session = options.session || (await createUcanSession({ id: options.sessionId, provider }));
709
764
  const address = await resolveAddress(provider, options.address);
710
765
  const chainId = options.chainId || (await getChainId(provider)) || '1';
711
- const domain = options.domain || (typeof window !== 'undefined' ? window.location.host : 'localhost');
712
- const uri = options.uri || (typeof window !== 'undefined' ? window.location.origin : 'http://localhost');
766
+ const domain = options.domain || (typeof window !== 'undefined' ? window.location.host : '127.0.0.1');
767
+ const uri = options.uri || (typeof window !== 'undefined' ? window.location.origin : 'http://127.0.0.1');
713
768
  const nonce = options.nonce || randomNonce(8);
714
769
  const exp = normalizeExpiry(undefined, options.expiresInMs ?? DEFAULT_SESSION_TTL);
715
770
  const nbf = options.notBeforeMs;
@@ -1058,6 +1113,7 @@ function createWebDavClient(options) {
1058
1113
 
1059
1114
  const tokenCache = new Map();
1060
1115
  const TOKEN_SKEW_MS = 5000;
1116
+ const DEFAULT_APP_ACTION = 'write';
1061
1117
  function normalizeAppDir(path) {
1062
1118
  const trimmed = path.trim();
1063
1119
  if (!trimmed)
@@ -1069,6 +1125,42 @@ function normalizeAppDir(path) {
1069
1125
  function sanitizeAppId(appId) {
1070
1126
  return appId.trim().replace(/[^a-zA-Z0-9._-]/g, '-');
1071
1127
  }
1128
+ function normalizeAction(action) {
1129
+ const trimmed = (action || '').trim();
1130
+ return trimmed ? trimmed : null;
1131
+ }
1132
+ function buildAppCapability(options) {
1133
+ if (!options.appId)
1134
+ return null;
1135
+ const action = normalizeAction(options.appAction) || DEFAULT_APP_ACTION;
1136
+ return {
1137
+ resource: `app:${sanitizeAppId(options.appId)}`,
1138
+ action,
1139
+ };
1140
+ }
1141
+ function hasAppCapability(caps) {
1142
+ return (caps || []).some(cap => typeof cap?.resource === 'string' && cap.resource.startsWith('app:'));
1143
+ }
1144
+ function dedupeCapabilities(caps) {
1145
+ const seen = new Set();
1146
+ return (caps || []).filter(cap => {
1147
+ if (!cap || !cap.resource || !cap.action)
1148
+ return false;
1149
+ const key = `${cap.resource}|${cap.action}`;
1150
+ if (seen.has(key))
1151
+ return false;
1152
+ seen.add(key);
1153
+ return true;
1154
+ });
1155
+ }
1156
+ function ensureAppCapability(caps, options) {
1157
+ const appCap = buildAppCapability(options);
1158
+ if (!appCap)
1159
+ return caps || [];
1160
+ if (hasAppCapability(caps || []))
1161
+ return caps || [];
1162
+ return dedupeCapabilities([...(caps || []), appCap]);
1163
+ }
1072
1164
  function resolveAppDir(options) {
1073
1165
  if (options.appDir) {
1074
1166
  return normalizeAppDir(options.appDir);
@@ -1084,6 +1176,14 @@ function buildCapsKey(caps) {
1084
1176
  function buildTokenCacheKey(issuer, audience, caps) {
1085
1177
  return `${issuer.did}|${audience}|${buildCapsKey(caps)}`;
1086
1178
  }
1179
+ function resolveWebdavCaps(options) {
1180
+ const baseCaps = options.capabilities || options.root?.cap || [];
1181
+ return ensureAppCapability(baseCaps, options);
1182
+ }
1183
+ function resolveInvocationCaps(options, fallbackCaps) {
1184
+ const caps = options.invocationCapabilities || fallbackCaps;
1185
+ return ensureAppCapability(caps, options);
1186
+ }
1087
1187
  function isTokenValid(entry, nowMs) {
1088
1188
  if (!entry.exp)
1089
1189
  return false;
@@ -1155,7 +1255,7 @@ async function getCachedInvocationToken(options) {
1155
1255
  return token;
1156
1256
  }
1157
1257
  async function initWebDavStorage(options) {
1158
- const caps = options.capabilities || options.root?.cap;
1258
+ const caps = resolveWebdavCaps(options);
1159
1259
  if (!caps || caps.length === 0) {
1160
1260
  throw new Error('Missing UCAN capabilities for WebDAV');
1161
1261
  }
@@ -1185,7 +1285,7 @@ async function initWebDavStorage(options) {
1185
1285
  expiresInMs: options.rootExpiresInMs,
1186
1286
  });
1187
1287
  }
1188
- const invocationCaps = options.invocationCapabilities || caps;
1288
+ const invocationCaps = resolveInvocationCaps(options, caps);
1189
1289
  const token = await getCachedInvocationToken({
1190
1290
  issuer: session,
1191
1291
  audience: options.audience,
@@ -1248,5 +1348,5 @@ async function initDappSession(options) {
1248
1348
  return result;
1249
1349
  }
1250
1350
 
1251
- export { WebDavClient, authFetch, authUcanFetch, clearAccessToken, clearUcanSession, createDelegationUcan, createInvocationUcan, createRootUcan, createUcanSession, createWebDavClient, getAccessToken, getAccounts, getBalance, getChainId, getOrCreateUcanRoot, getProvider, getStoredUcanRoot, getUcanSession, initDappSession, initWebDavStorage, isYeYingProvider, loginWithChallenge, logout, onAccountsChanged, onChainChanged, refreshAccessToken, requestAccounts, requireProvider, setAccessToken, signMessage, storeUcanRoot };
1351
+ export { WebDavClient, authFetch, authUcanFetch, clearAccessToken, clearUcanSession, createDelegationUcan, createInvocationUcan, createRootUcan, createUcanSession, createWebDavClient, getAccessToken, getAccounts, getBalance, getChainId, getOrCreateUcanRoot, getPreferredAccount, getProvider, getStoredUcanRoot, getUcanSession, initDappSession, initWebDavStorage, isYeYingProvider, loginWithChallenge, logout, onAccountsChanged, onChainChanged, refreshAccessToken, requestAccounts, requireProvider, setAccessToken, signMessage, storeUcanRoot, watchAccounts };
1252
1352
  //# sourceMappingURL=web3-bs.esm.js.map