@yeying-community/web3-bs 1.0.8 → 1.0.10
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 +4 -0
- package/dist/auth/provider.d.ts +7 -1
- package/dist/auth/types.d.ts +17 -0
- package/dist/web3-bs.esm.js +171 -9
- package/dist/web3-bs.esm.js.map +1 -1
- package/dist/web3-bs.umd.js +176 -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,24 @@
|
|
|
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
|
+
}
|
|
140
302
|
}
|
|
141
303
|
async function getAccounts(provider) {
|
|
142
304
|
const p = provider || (await requireProvider());
|
|
@@ -2014,6 +2176,7 @@
|
|
|
2014
2176
|
exports.authCentralUcanFetch = authCentralUcanFetch;
|
|
2015
2177
|
exports.authFetch = authFetch;
|
|
2016
2178
|
exports.authUcanFetch = authUcanFetch;
|
|
2179
|
+
exports.classifyWalletError = classifyWalletError;
|
|
2017
2180
|
exports.clearAccessToken = clearAccessToken;
|
|
2018
2181
|
exports.clearCentralSessionToken = clearCentralSessionToken;
|
|
2019
2182
|
exports.clearUcanSession = clearUcanSession;
|
|
@@ -2039,8 +2202,12 @@
|
|
|
2039
2202
|
exports.getProvider = getProvider;
|
|
2040
2203
|
exports.getStoredUcanRoot = getStoredUcanRoot;
|
|
2041
2204
|
exports.getUcanSession = getUcanSession;
|
|
2205
|
+
exports.getWalletErrorCode = getWalletErrorCode;
|
|
2206
|
+
exports.getWalletErrorMessage = getWalletErrorMessage;
|
|
2042
2207
|
exports.initDappSession = initDappSession;
|
|
2043
2208
|
exports.initWebDavStorage = initWebDavStorage;
|
|
2209
|
+
exports.isUserRejectedWalletAction = isUserRejectedWalletAction;
|
|
2210
|
+
exports.isWalletReconnectError = isWalletReconnectError;
|
|
2044
2211
|
exports.isYeYingProvider = isYeYingProvider;
|
|
2045
2212
|
exports.issueCentralUcan = issueCentralUcan;
|
|
2046
2213
|
exports.loginWithChallenge = loginWithChallenge;
|
|
@@ -2058,6 +2225,7 @@
|
|
|
2058
2225
|
exports.signMessage = signMessage;
|
|
2059
2226
|
exports.storeUcanRoot = storeUcanRoot;
|
|
2060
2227
|
exports.watchAccounts = watchAccounts;
|
|
2228
|
+
exports.watchProvider = watchProvider;
|
|
2061
2229
|
|
|
2062
2230
|
}));
|
|
2063
2231
|
//# sourceMappingURL=web3-bs.umd.js.map
|