@yeying-community/web3-bs 1.0.8 → 1.0.11
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 +17 -2
- package/dist/auth/provider.d.ts +8 -1
- package/dist/auth/types.d.ts +24 -0
- package/dist/web3-bs.esm.js +190 -9
- package/dist/web3-bs.esm.js.map +1 -1
- package/dist/web3-bs.umd.js +196 -8
- package/dist/web3-bs.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/web3-bs.umd.js
CHANGED
|
@@ -7,10 +7,46 @@
|
|
|
7
7
|
const YEYING_RDNS = 'io.github.yeying';
|
|
8
8
|
const DEFAULT_TIMEOUT = 1000;
|
|
9
9
|
const DEFAULT_ACCOUNT_STORAGE_KEY = 'yeying:last_account';
|
|
10
|
+
const DEFAULT_PROVIDER_POLL_INTERVAL = 100;
|
|
11
|
+
const DEFAULT_PROVIDER_MAX_POLLS = 20;
|
|
12
|
+
const requestAccountsInFlight = new WeakMap();
|
|
13
|
+
function isProvider(value) {
|
|
14
|
+
return !!value && typeof value.request === 'function';
|
|
15
|
+
}
|
|
10
16
|
function getWindowEthereum() {
|
|
11
17
|
if (typeof window === 'undefined')
|
|
12
18
|
return null;
|
|
13
|
-
|
|
19
|
+
const ethereum = window.ethereum;
|
|
20
|
+
return isProvider(ethereum) ? ethereum : null;
|
|
21
|
+
}
|
|
22
|
+
function getWindowProviderCandidates() {
|
|
23
|
+
if (typeof window === 'undefined')
|
|
24
|
+
return [];
|
|
25
|
+
const source = window;
|
|
26
|
+
const candidates = [];
|
|
27
|
+
const addProvider = (provider) => {
|
|
28
|
+
if (isProvider(provider) && !candidates.includes(provider)) {
|
|
29
|
+
candidates.push(provider);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
for (const name of [
|
|
33
|
+
'ethereum',
|
|
34
|
+
'yeeying',
|
|
35
|
+
'yeying',
|
|
36
|
+
'coinbaseWallet',
|
|
37
|
+
'bitkeep',
|
|
38
|
+
'tokenpocket',
|
|
39
|
+
'__YEYING_PROVIDER__',
|
|
40
|
+
]) {
|
|
41
|
+
addProvider(source[name]);
|
|
42
|
+
}
|
|
43
|
+
const ethereum = getWindowEthereum();
|
|
44
|
+
if (Array.isArray(ethereum?.providers)) {
|
|
45
|
+
for (const provider of ethereum.providers) {
|
|
46
|
+
addProvider(provider);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return candidates;
|
|
14
50
|
}
|
|
15
51
|
function readStoredAccount(storageKey) {
|
|
16
52
|
if (typeof localStorage === 'undefined')
|
|
@@ -54,7 +90,7 @@
|
|
|
54
90
|
}
|
|
55
91
|
function selectBestProvider(candidates, preferYeYing) {
|
|
56
92
|
if (candidates.length === 0)
|
|
57
|
-
return
|
|
93
|
+
return selectBestWindowProvider(preferYeYing);
|
|
58
94
|
if (preferYeYing) {
|
|
59
95
|
const yeying = candidates.find(c => isYeYingProvider(c.provider, c.info));
|
|
60
96
|
if (yeying)
|
|
@@ -62,10 +98,21 @@
|
|
|
62
98
|
}
|
|
63
99
|
return candidates[0].provider;
|
|
64
100
|
}
|
|
101
|
+
function selectBestWindowProvider(preferYeYing) {
|
|
102
|
+
const candidates = getWindowProviderCandidates();
|
|
103
|
+
if (candidates.length === 0)
|
|
104
|
+
return null;
|
|
105
|
+
if (preferYeYing) {
|
|
106
|
+
const yeying = candidates.find(provider => isYeYingProvider(provider));
|
|
107
|
+
if (yeying)
|
|
108
|
+
return yeying;
|
|
109
|
+
}
|
|
110
|
+
return candidates[0];
|
|
111
|
+
}
|
|
65
112
|
async function getProvider(options = {}) {
|
|
66
113
|
const preferYeYing = options.preferYeYing !== false;
|
|
67
114
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT;
|
|
68
|
-
const windowProvider =
|
|
115
|
+
const windowProvider = selectBestWindowProvider(preferYeYing);
|
|
69
116
|
if (preferYeYing && isYeYingProvider(windowProvider)) {
|
|
70
117
|
return windowProvider;
|
|
71
118
|
}
|
|
@@ -98,7 +145,7 @@
|
|
|
98
145
|
}
|
|
99
146
|
};
|
|
100
147
|
const onEthereumInitialized = () => {
|
|
101
|
-
const injected =
|
|
148
|
+
const injected = selectBestWindowProvider(preferYeYing);
|
|
102
149
|
if (preferYeYing && isYeYingProvider(injected)) {
|
|
103
150
|
safeResolve(injected);
|
|
104
151
|
}
|
|
@@ -110,7 +157,7 @@
|
|
|
110
157
|
return;
|
|
111
158
|
const best = selectBestProvider(discovered, preferYeYing) ||
|
|
112
159
|
windowProvider ||
|
|
113
|
-
|
|
160
|
+
selectBestWindowProvider(preferYeYing);
|
|
114
161
|
safeResolve(best || null);
|
|
115
162
|
}, timeoutMs);
|
|
116
163
|
try {
|
|
@@ -124,6 +171,107 @@
|
|
|
124
171
|
}
|
|
125
172
|
});
|
|
126
173
|
}
|
|
174
|
+
function watchProvider(handler, options = {}) {
|
|
175
|
+
if (typeof window === 'undefined') {
|
|
176
|
+
handler({ provider: null, present: false });
|
|
177
|
+
return () => { };
|
|
178
|
+
}
|
|
179
|
+
const preferYeYing = options.preferYeYing !== false;
|
|
180
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_PROVIDER_POLL_INTERVAL;
|
|
181
|
+
const maxPolls = options.maxPolls ?? DEFAULT_PROVIDER_MAX_POLLS;
|
|
182
|
+
let stopped = false;
|
|
183
|
+
let lastProvider;
|
|
184
|
+
let pollCount = 0;
|
|
185
|
+
let pollTimer = null;
|
|
186
|
+
const emit = () => {
|
|
187
|
+
if (stopped)
|
|
188
|
+
return;
|
|
189
|
+
const provider = selectBestWindowProvider(preferYeYing);
|
|
190
|
+
if (provider === lastProvider)
|
|
191
|
+
return;
|
|
192
|
+
lastProvider = provider;
|
|
193
|
+
handler({ provider, present: !!provider });
|
|
194
|
+
};
|
|
195
|
+
const poll = () => {
|
|
196
|
+
if (stopped)
|
|
197
|
+
return;
|
|
198
|
+
emit();
|
|
199
|
+
pollCount += 1;
|
|
200
|
+
if (lastProvider || pollCount >= maxPolls)
|
|
201
|
+
return;
|
|
202
|
+
pollTimer = setTimeout(poll, pollIntervalMs);
|
|
203
|
+
};
|
|
204
|
+
const handleProviderReady = () => {
|
|
205
|
+
emit();
|
|
206
|
+
};
|
|
207
|
+
window.addEventListener('ethereum#initialized', handleProviderReady);
|
|
208
|
+
window.addEventListener('eip6963:announceProvider', handleProviderReady);
|
|
209
|
+
try {
|
|
210
|
+
window.dispatchEvent(new Event('eip6963:requestProvider'));
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
// Ignore unsupported event dispatch environments.
|
|
214
|
+
}
|
|
215
|
+
poll();
|
|
216
|
+
return () => {
|
|
217
|
+
stopped = true;
|
|
218
|
+
if (pollTimer) {
|
|
219
|
+
clearTimeout(pollTimer);
|
|
220
|
+
}
|
|
221
|
+
window.removeEventListener('ethereum#initialized', handleProviderReady);
|
|
222
|
+
window.removeEventListener('eip6963:announceProvider', handleProviderReady);
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function getWalletErrorMessage(error) {
|
|
226
|
+
if (!error)
|
|
227
|
+
return '';
|
|
228
|
+
if (typeof error === 'string')
|
|
229
|
+
return error;
|
|
230
|
+
if (error instanceof Error)
|
|
231
|
+
return error.message || String(error);
|
|
232
|
+
const message = error.message;
|
|
233
|
+
if (typeof message === 'string')
|
|
234
|
+
return message;
|
|
235
|
+
return String(error);
|
|
236
|
+
}
|
|
237
|
+
function getWalletErrorCode(error) {
|
|
238
|
+
const code = Number(error?.code);
|
|
239
|
+
if (!Number.isNaN(code))
|
|
240
|
+
return code;
|
|
241
|
+
const causeCode = Number(error?.cause?.code);
|
|
242
|
+
if (!Number.isNaN(causeCode))
|
|
243
|
+
return causeCode;
|
|
244
|
+
return null;
|
|
245
|
+
}
|
|
246
|
+
function classifyWalletError(error) {
|
|
247
|
+
const code = getWalletErrorCode(error);
|
|
248
|
+
const message = getWalletErrorMessage(error);
|
|
249
|
+
const lowerMessage = message.toLowerCase();
|
|
250
|
+
if (code === 4001 || lowerMessage.includes('user rejected')) {
|
|
251
|
+
return { type: 'userRejected', code, message };
|
|
252
|
+
}
|
|
253
|
+
if (code === 4900 ||
|
|
254
|
+
lowerMessage.includes('disconnected') ||
|
|
255
|
+
lowerMessage.includes('reconnect') ||
|
|
256
|
+
lowerMessage.includes('not connected')) {
|
|
257
|
+
return { type: 'disconnected', code, message };
|
|
258
|
+
}
|
|
259
|
+
if (lowerMessage.includes('timeout')) {
|
|
260
|
+
return { type: 'timeout', code, message };
|
|
261
|
+
}
|
|
262
|
+
if (lowerMessage.includes('no injected wallet provider') ||
|
|
263
|
+
lowerMessage.includes('未检测到钱包')) {
|
|
264
|
+
return { type: 'notFound', code, message };
|
|
265
|
+
}
|
|
266
|
+
return { type: 'unknown', code, message };
|
|
267
|
+
}
|
|
268
|
+
function isUserRejectedWalletAction(error) {
|
|
269
|
+
return classifyWalletError(error).type === 'userRejected';
|
|
270
|
+
}
|
|
271
|
+
function isWalletReconnectError(error) {
|
|
272
|
+
const type = classifyWalletError(error).type;
|
|
273
|
+
return type === 'disconnected' || type === 'timeout';
|
|
274
|
+
}
|
|
127
275
|
async function requireProvider(options = {}) {
|
|
128
276
|
const provider = await getProvider(options);
|
|
129
277
|
if (!provider) {
|
|
@@ -133,10 +281,43 @@
|
|
|
133
281
|
}
|
|
134
282
|
async function requestAccounts(options = {}) {
|
|
135
283
|
const provider = options.provider || (await requireProvider());
|
|
136
|
-
const
|
|
284
|
+
const dedupe = options.dedupe !== false;
|
|
285
|
+
if (dedupe) {
|
|
286
|
+
const pending = requestAccountsInFlight.get(provider);
|
|
287
|
+
if (pending)
|
|
288
|
+
return pending;
|
|
289
|
+
}
|
|
290
|
+
const request = provider.request({
|
|
137
291
|
method: 'eth_requestAccounts',
|
|
138
|
-
}));
|
|
139
|
-
|
|
292
|
+
}).then(accounts => (Array.isArray(accounts) ? accounts : []));
|
|
293
|
+
if (!dedupe)
|
|
294
|
+
return request;
|
|
295
|
+
requestAccountsInFlight.set(provider, request);
|
|
296
|
+
try {
|
|
297
|
+
return await request;
|
|
298
|
+
}
|
|
299
|
+
finally {
|
|
300
|
+
requestAccountsInFlight.delete(provider);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
async function focusPendingApproval(provider) {
|
|
304
|
+
const p = provider || (await requireProvider());
|
|
305
|
+
const result = await p.request({
|
|
306
|
+
method: 'wallet_focusPendingApproval',
|
|
307
|
+
});
|
|
308
|
+
if (!result || typeof result !== 'object') {
|
|
309
|
+
return { focused: false, type: null };
|
|
310
|
+
}
|
|
311
|
+
const payload = result;
|
|
312
|
+
return {
|
|
313
|
+
focused: Boolean(payload.focused),
|
|
314
|
+
type: typeof payload.type === 'string' ? payload.type : null,
|
|
315
|
+
requestId: typeof payload.requestId === 'string' ? payload.requestId : null,
|
|
316
|
+
origin: typeof payload.origin === 'string' ? payload.origin : '',
|
|
317
|
+
tabId: typeof payload.tabId === 'number' && Number.isFinite(payload.tabId)
|
|
318
|
+
? payload.tabId
|
|
319
|
+
: null,
|
|
320
|
+
};
|
|
140
321
|
}
|
|
141
322
|
async function getAccounts(provider) {
|
|
142
323
|
const p = provider || (await requireProvider());
|
|
@@ -2014,6 +2195,7 @@
|
|
|
2014
2195
|
exports.authCentralUcanFetch = authCentralUcanFetch;
|
|
2015
2196
|
exports.authFetch = authFetch;
|
|
2016
2197
|
exports.authUcanFetch = authUcanFetch;
|
|
2198
|
+
exports.classifyWalletError = classifyWalletError;
|
|
2017
2199
|
exports.clearAccessToken = clearAccessToken;
|
|
2018
2200
|
exports.clearCentralSessionToken = clearCentralSessionToken;
|
|
2019
2201
|
exports.clearUcanSession = clearUcanSession;
|
|
@@ -2026,6 +2208,7 @@
|
|
|
2026
2208
|
exports.createWebDavClient = createWebDavClient;
|
|
2027
2209
|
exports.deriveAppIdFromHost = deriveAppIdFromHost;
|
|
2028
2210
|
exports.deriveAppIdFromLocation = deriveAppIdFromLocation;
|
|
2211
|
+
exports.focusPendingApproval = focusPendingApproval;
|
|
2029
2212
|
exports.getAccessToken = getAccessToken;
|
|
2030
2213
|
exports.getAccounts = getAccounts;
|
|
2031
2214
|
exports.getBalance = getBalance;
|
|
@@ -2039,8 +2222,12 @@
|
|
|
2039
2222
|
exports.getProvider = getProvider;
|
|
2040
2223
|
exports.getStoredUcanRoot = getStoredUcanRoot;
|
|
2041
2224
|
exports.getUcanSession = getUcanSession;
|
|
2225
|
+
exports.getWalletErrorCode = getWalletErrorCode;
|
|
2226
|
+
exports.getWalletErrorMessage = getWalletErrorMessage;
|
|
2042
2227
|
exports.initDappSession = initDappSession;
|
|
2043
2228
|
exports.initWebDavStorage = initWebDavStorage;
|
|
2229
|
+
exports.isUserRejectedWalletAction = isUserRejectedWalletAction;
|
|
2230
|
+
exports.isWalletReconnectError = isWalletReconnectError;
|
|
2044
2231
|
exports.isYeYingProvider = isYeYingProvider;
|
|
2045
2232
|
exports.issueCentralUcan = issueCentralUcan;
|
|
2046
2233
|
exports.loginWithChallenge = loginWithChallenge;
|
|
@@ -2058,6 +2245,7 @@
|
|
|
2058
2245
|
exports.signMessage = signMessage;
|
|
2059
2246
|
exports.storeUcanRoot = storeUcanRoot;
|
|
2060
2247
|
exports.watchAccounts = watchAccounts;
|
|
2248
|
+
exports.watchProvider = watchProvider;
|
|
2061
2249
|
|
|
2062
2250
|
}));
|
|
2063
2251
|
//# sourceMappingURL=web3-bs.umd.js.map
|