@earthworm/wallet-sdk 0.2.1 → 0.2.3
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 +55 -5
- package/dist/account-sync-77HMBIWC.js +2 -0
- package/dist/chunk-BUZ26NFL.js +48 -0
- package/dist/chunk-TPFOHQNS.js +40 -0
- package/dist/chunk-Z2EMFRMV.js +1065 -0
- package/dist/index.d.ts +453 -243
- package/dist/index.js +150 -686
- package/dist/network-WJN3S7KB.js +2 -0
- package/package.json +2 -1
|
@@ -0,0 +1,1065 @@
|
|
|
1
|
+
import { BrowserProvider, Contract, formatUnits, JsonRpcProvider } from 'ethers';
|
|
2
|
+
|
|
3
|
+
// src/utils/chain.ts
|
|
4
|
+
function toChainIdDecimal(chainId, fallback) {
|
|
5
|
+
const decimal = Number.parseInt(chainId, 16);
|
|
6
|
+
if (Number.isFinite(decimal)) return decimal;
|
|
7
|
+
if (fallback !== void 0) return fallback;
|
|
8
|
+
return Number.NaN;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// src/utils/env.ts
|
|
12
|
+
var isBrowser = typeof window !== "undefined";
|
|
13
|
+
function assertBrowser(apiName) {
|
|
14
|
+
if (!isBrowser) {
|
|
15
|
+
throw new Error(`[wallet-sdk] ${apiName} is only available in the browser`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
var providerCache = /* @__PURE__ */ new WeakMap();
|
|
19
|
+
function resetSharedBrowserProvider(ethereum) {
|
|
20
|
+
providerCache.delete(ethereum);
|
|
21
|
+
}
|
|
22
|
+
function getSharedBrowserProvider(ethereum) {
|
|
23
|
+
const cached = providerCache.get(ethereum);
|
|
24
|
+
if (cached) {
|
|
25
|
+
return cached;
|
|
26
|
+
}
|
|
27
|
+
const provider = new BrowserProvider(ethereum);
|
|
28
|
+
providerCache.set(ethereum, provider);
|
|
29
|
+
return provider;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/abi/erc20.ts
|
|
33
|
+
var ERC20_ABI = [
|
|
34
|
+
{
|
|
35
|
+
constant: true,
|
|
36
|
+
inputs: [],
|
|
37
|
+
name: "name",
|
|
38
|
+
outputs: [
|
|
39
|
+
{
|
|
40
|
+
name: "",
|
|
41
|
+
type: "string"
|
|
42
|
+
}
|
|
43
|
+
],
|
|
44
|
+
payable: false,
|
|
45
|
+
stateMutability: "view",
|
|
46
|
+
type: "function"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
constant: false,
|
|
50
|
+
inputs: [
|
|
51
|
+
{
|
|
52
|
+
name: "_spender",
|
|
53
|
+
type: "address"
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "_value",
|
|
57
|
+
type: "uint256"
|
|
58
|
+
}
|
|
59
|
+
],
|
|
60
|
+
name: "approve",
|
|
61
|
+
outputs: [
|
|
62
|
+
{
|
|
63
|
+
name: "success",
|
|
64
|
+
type: "bool"
|
|
65
|
+
}
|
|
66
|
+
],
|
|
67
|
+
payable: false,
|
|
68
|
+
stateMutability: "nonpayable",
|
|
69
|
+
type: "function"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
constant: true,
|
|
73
|
+
inputs: [],
|
|
74
|
+
name: "totalSupply",
|
|
75
|
+
outputs: [
|
|
76
|
+
{
|
|
77
|
+
name: "",
|
|
78
|
+
type: "uint256"
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
payable: false,
|
|
82
|
+
stateMutability: "view",
|
|
83
|
+
type: "function"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
constant: false,
|
|
87
|
+
inputs: [
|
|
88
|
+
{
|
|
89
|
+
name: "_from",
|
|
90
|
+
type: "address"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: "_to",
|
|
94
|
+
type: "address"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "_value",
|
|
98
|
+
type: "uint256"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
name: "transferFrom",
|
|
102
|
+
outputs: [
|
|
103
|
+
{
|
|
104
|
+
name: "success",
|
|
105
|
+
type: "bool"
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
payable: false,
|
|
109
|
+
stateMutability: "nonpayable",
|
|
110
|
+
type: "function"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
constant: true,
|
|
114
|
+
inputs: [],
|
|
115
|
+
name: "decimals",
|
|
116
|
+
outputs: [
|
|
117
|
+
{
|
|
118
|
+
name: "",
|
|
119
|
+
type: "uint8"
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
payable: false,
|
|
123
|
+
stateMutability: "view",
|
|
124
|
+
type: "function"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
constant: false,
|
|
128
|
+
inputs: [
|
|
129
|
+
{
|
|
130
|
+
name: "_value",
|
|
131
|
+
type: "uint256"
|
|
132
|
+
}
|
|
133
|
+
],
|
|
134
|
+
name: "burn",
|
|
135
|
+
outputs: [],
|
|
136
|
+
payable: false,
|
|
137
|
+
stateMutability: "nonpayable",
|
|
138
|
+
type: "function"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
constant: true,
|
|
142
|
+
inputs: [
|
|
143
|
+
{
|
|
144
|
+
name: "_owner",
|
|
145
|
+
type: "address"
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
name: "balanceOf",
|
|
149
|
+
outputs: [
|
|
150
|
+
{
|
|
151
|
+
name: "balance",
|
|
152
|
+
type: "uint256"
|
|
153
|
+
}
|
|
154
|
+
],
|
|
155
|
+
payable: false,
|
|
156
|
+
stateMutability: "view",
|
|
157
|
+
type: "function"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
constant: false,
|
|
161
|
+
inputs: [
|
|
162
|
+
{
|
|
163
|
+
name: "_from",
|
|
164
|
+
type: "address"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: "_value",
|
|
168
|
+
type: "uint256"
|
|
169
|
+
}
|
|
170
|
+
],
|
|
171
|
+
name: "burnFrom",
|
|
172
|
+
outputs: [],
|
|
173
|
+
payable: false,
|
|
174
|
+
stateMutability: "nonpayable",
|
|
175
|
+
type: "function"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
constant: false,
|
|
179
|
+
inputs: [
|
|
180
|
+
{
|
|
181
|
+
name: "_to",
|
|
182
|
+
type: "address[]"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "_value",
|
|
186
|
+
type: "uint256[]"
|
|
187
|
+
}
|
|
188
|
+
],
|
|
189
|
+
name: "transferArray",
|
|
190
|
+
outputs: [],
|
|
191
|
+
payable: false,
|
|
192
|
+
stateMutability: "nonpayable",
|
|
193
|
+
type: "function"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
constant: true,
|
|
197
|
+
inputs: [],
|
|
198
|
+
name: "symbol",
|
|
199
|
+
outputs: [
|
|
200
|
+
{
|
|
201
|
+
name: "",
|
|
202
|
+
type: "string"
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
payable: false,
|
|
206
|
+
stateMutability: "view",
|
|
207
|
+
type: "function"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
constant: false,
|
|
211
|
+
inputs: [
|
|
212
|
+
{
|
|
213
|
+
name: "_to",
|
|
214
|
+
type: "address"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
name: "_value",
|
|
218
|
+
type: "uint256"
|
|
219
|
+
}
|
|
220
|
+
],
|
|
221
|
+
name: "transfer",
|
|
222
|
+
outputs: [
|
|
223
|
+
{
|
|
224
|
+
name: "success",
|
|
225
|
+
type: "bool"
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
payable: false,
|
|
229
|
+
stateMutability: "nonpayable",
|
|
230
|
+
type: "function"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
constant: true,
|
|
234
|
+
inputs: [
|
|
235
|
+
{
|
|
236
|
+
name: "_owner",
|
|
237
|
+
type: "address"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
name: "_spender",
|
|
241
|
+
type: "address"
|
|
242
|
+
}
|
|
243
|
+
],
|
|
244
|
+
name: "allowance",
|
|
245
|
+
outputs: [
|
|
246
|
+
{
|
|
247
|
+
name: "remaining",
|
|
248
|
+
type: "uint256"
|
|
249
|
+
}
|
|
250
|
+
],
|
|
251
|
+
payable: false,
|
|
252
|
+
stateMutability: "view",
|
|
253
|
+
type: "function"
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
inputs: [
|
|
257
|
+
{
|
|
258
|
+
name: "_tokenName",
|
|
259
|
+
type: "string"
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
name: "_tokenSymbol",
|
|
263
|
+
type: "string"
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: "_decimalUnits",
|
|
267
|
+
type: "uint8"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: "_initialAmount",
|
|
271
|
+
type: "uint256"
|
|
272
|
+
}
|
|
273
|
+
],
|
|
274
|
+
payable: false,
|
|
275
|
+
stateMutability: "nonpayable",
|
|
276
|
+
type: "constructor"
|
|
277
|
+
},
|
|
278
|
+
{
|
|
279
|
+
anonymous: false,
|
|
280
|
+
inputs: [
|
|
281
|
+
{
|
|
282
|
+
indexed: true,
|
|
283
|
+
name: "from",
|
|
284
|
+
type: "address"
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
indexed: true,
|
|
288
|
+
name: "to",
|
|
289
|
+
type: "address"
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
indexed: false,
|
|
293
|
+
name: "value",
|
|
294
|
+
type: "uint256"
|
|
295
|
+
}
|
|
296
|
+
],
|
|
297
|
+
name: "Transfer",
|
|
298
|
+
type: "event"
|
|
299
|
+
},
|
|
300
|
+
{
|
|
301
|
+
anonymous: false,
|
|
302
|
+
inputs: [
|
|
303
|
+
{
|
|
304
|
+
indexed: true,
|
|
305
|
+
name: "owner",
|
|
306
|
+
type: "address"
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
indexed: true,
|
|
310
|
+
name: "spender",
|
|
311
|
+
type: "address"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
indexed: false,
|
|
315
|
+
name: "value",
|
|
316
|
+
type: "uint256"
|
|
317
|
+
}
|
|
318
|
+
],
|
|
319
|
+
name: "Approval",
|
|
320
|
+
type: "event"
|
|
321
|
+
}
|
|
322
|
+
];
|
|
323
|
+
|
|
324
|
+
// src/config/networks.ts
|
|
325
|
+
var BSC_NETWORK = {
|
|
326
|
+
chainId: "0x38",
|
|
327
|
+
chainName: "BNB Smart Chain",
|
|
328
|
+
nativeCurrency: {
|
|
329
|
+
name: "BNB",
|
|
330
|
+
symbol: "BNB",
|
|
331
|
+
decimals: 18
|
|
332
|
+
},
|
|
333
|
+
rpcUrls: [
|
|
334
|
+
"https://bsc-dataseed.binance.org/",
|
|
335
|
+
"https://bsc-dataseed1.binance.org/",
|
|
336
|
+
"https://bsc-dataseed2.binance.org/"
|
|
337
|
+
],
|
|
338
|
+
blockExplorerUrls: ["https://bscscan.com"]
|
|
339
|
+
};
|
|
340
|
+
var BSC_TESTNET_NETWORK = {
|
|
341
|
+
chainId: "0x61",
|
|
342
|
+
chainName: "BNB Smart Chain Testnet",
|
|
343
|
+
nativeCurrency: {
|
|
344
|
+
name: "tBNB",
|
|
345
|
+
symbol: "tBNB",
|
|
346
|
+
decimals: 18
|
|
347
|
+
},
|
|
348
|
+
rpcUrls: [
|
|
349
|
+
"https://data-seed-prebsc-1-s1.bnbchain.org:8545/",
|
|
350
|
+
"https://data-seed-prebsc-2-s1.bnbchain.org:8545/",
|
|
351
|
+
"https://data-seed-prebsc-1-s2.bnbchain.org:8545/"
|
|
352
|
+
],
|
|
353
|
+
blockExplorerUrls: ["https://testnet.bscscan.com"]
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
// src/config/resolve-chain.ts
|
|
357
|
+
var SUPPORTED_BSC_CHAIN_IDS = [
|
|
358
|
+
BSC_NETWORK.chainId,
|
|
359
|
+
BSC_TESTNET_NETWORK.chainId
|
|
360
|
+
];
|
|
361
|
+
function normalizeChainIdInput(chainId) {
|
|
362
|
+
if (typeof chainId === "number") {
|
|
363
|
+
return `0x${Number(chainId).toString(16)}`;
|
|
364
|
+
}
|
|
365
|
+
const trimmed = chainId.trim();
|
|
366
|
+
if (trimmed.startsWith("0x") || trimmed.startsWith("0X")) {
|
|
367
|
+
return `0x${trimmed.slice(2).toLowerCase()}`;
|
|
368
|
+
}
|
|
369
|
+
const decimal = Number.parseInt(trimmed, 10);
|
|
370
|
+
if (Number.isFinite(decimal)) {
|
|
371
|
+
return `0x${decimal.toString(16)}`;
|
|
372
|
+
}
|
|
373
|
+
return trimmed.toLowerCase();
|
|
374
|
+
}
|
|
375
|
+
function normalizeSupportedBscChainId(chainId) {
|
|
376
|
+
const normalized = normalizeChainIdInput(chainId);
|
|
377
|
+
if (normalized === BSC_NETWORK.chainId) {
|
|
378
|
+
return BSC_NETWORK.chainId;
|
|
379
|
+
}
|
|
380
|
+
if (normalized === BSC_TESTNET_NETWORK.chainId) {
|
|
381
|
+
return BSC_TESTNET_NETWORK.chainId;
|
|
382
|
+
}
|
|
383
|
+
throw new Error(
|
|
384
|
+
`[wallet-sdk] Unsupported chainId: ${chainId}. Only BSC mainnet (${BSC_NETWORK.chainId}) and testnet (${BSC_TESTNET_NETWORK.chainId}) are supported.`
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
function resolveChainConfig(chainId) {
|
|
388
|
+
return chainId === BSC_NETWORK.chainId ? BSC_NETWORK : BSC_TESTNET_NETWORK;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// src/config/usdt.ts
|
|
392
|
+
var USDT_CONFIG = {
|
|
393
|
+
symbol: "USDT",
|
|
394
|
+
name: "Tether USD",
|
|
395
|
+
decimals: 18,
|
|
396
|
+
contractAbi: ERC20_ABI
|
|
397
|
+
};
|
|
398
|
+
var ERC20_DECIMALS = USDT_CONFIG.decimals;
|
|
399
|
+
var ERC20_DECIMALS_ABI = ["function decimals() view returns (uint8)"];
|
|
400
|
+
async function hasDeployedContract(readProvider, address) {
|
|
401
|
+
const code = await readProvider.getCode(address);
|
|
402
|
+
return Boolean(code && code !== "0x");
|
|
403
|
+
}
|
|
404
|
+
async function readErc20Decimals(readProvider, tokenAddress, erc20Abi = ERC20_DECIMALS_ABI, fallback = ERC20_DECIMALS) {
|
|
405
|
+
if (!await hasDeployedContract(readProvider, tokenAddress)) {
|
|
406
|
+
throw new Error(`[wallet-sdk] Token contract not deployed: ${tokenAddress}`);
|
|
407
|
+
}
|
|
408
|
+
try {
|
|
409
|
+
const tokenContract = new Contract(tokenAddress, erc20Abi, readProvider);
|
|
410
|
+
const decimals = Number(await tokenContract.getFunction("decimals").staticCall());
|
|
411
|
+
return Number.isFinite(decimals) && decimals >= 0 ? decimals : fallback;
|
|
412
|
+
} catch {
|
|
413
|
+
return fallback;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
async function readErc20Balance(readProvider, tokenAddress, accountAddress, erc20Abi = ERC20_ABI) {
|
|
417
|
+
if (!await hasDeployedContract(readProvider, tokenAddress)) {
|
|
418
|
+
throw new Error(`[wallet-sdk] Token contract not deployed: ${tokenAddress}`);
|
|
419
|
+
}
|
|
420
|
+
const tokenContract = new Contract(tokenAddress, erc20Abi, readProvider);
|
|
421
|
+
const [balance, decimals] = await Promise.all([
|
|
422
|
+
tokenContract.getFunction("balanceOf").staticCall(accountAddress),
|
|
423
|
+
readErc20Decimals(readProvider, tokenAddress, erc20Abi)
|
|
424
|
+
]);
|
|
425
|
+
return {
|
|
426
|
+
accountAddress,
|
|
427
|
+
balance: formatUnits(balance, decimals),
|
|
428
|
+
decimals
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
var jsonRpcReadProviderCache = { current: null };
|
|
432
|
+
function clearJsonRpcReadProviderCache() {
|
|
433
|
+
jsonRpcReadProviderCache.current = null;
|
|
434
|
+
}
|
|
435
|
+
function createJsonRpcReadProvider(rpcUrl, chainIdHex, cache) {
|
|
436
|
+
if (cache?.current) return cache.current;
|
|
437
|
+
const provider = new JsonRpcProvider(rpcUrl, toChainIdDecimal(chainIdHex), {
|
|
438
|
+
staticNetwork: true
|
|
439
|
+
});
|
|
440
|
+
if (cache) {
|
|
441
|
+
cache.current = provider;
|
|
442
|
+
}
|
|
443
|
+
return provider;
|
|
444
|
+
}
|
|
445
|
+
function getReadProviderWithFallback(walletProvider, rpcConfig, fallbackCache) {
|
|
446
|
+
if (walletProvider) return walletProvider;
|
|
447
|
+
const rpcUrl = rpcConfig.rpcUrls[0];
|
|
448
|
+
if (!rpcUrl || !rpcConfig.chainId) {
|
|
449
|
+
throw new Error("RPC config is missing");
|
|
450
|
+
}
|
|
451
|
+
return createJsonRpcReadProvider(rpcUrl, rpcConfig.chainId, fallbackCache);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// src/core/init.ts
|
|
455
|
+
var CONFIG_KEY = "__WALLET_SDK_CONFIG__";
|
|
456
|
+
var INITIALIZED_KEY = "__WALLET_SDK_INITIALIZED__";
|
|
457
|
+
function getStoredConfig() {
|
|
458
|
+
return globalThis[CONFIG_KEY] ?? null;
|
|
459
|
+
}
|
|
460
|
+
function isStoredInitialized() {
|
|
461
|
+
return Boolean(globalThis[INITIALIZED_KEY]);
|
|
462
|
+
}
|
|
463
|
+
function storeConfig(config) {
|
|
464
|
+
const globalState = globalThis;
|
|
465
|
+
globalState[CONFIG_KEY] = config;
|
|
466
|
+
globalState[INITIALIZED_KEY] = true;
|
|
467
|
+
}
|
|
468
|
+
function buildConfig(options) {
|
|
469
|
+
return {
|
|
470
|
+
usdt: {
|
|
471
|
+
address: options.usdt.address,
|
|
472
|
+
abi: USDT_CONFIG.contractAbi,
|
|
473
|
+
symbol: USDT_CONFIG.symbol,
|
|
474
|
+
name: USDT_CONFIG.name,
|
|
475
|
+
decimals: USDT_CONFIG.decimals
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
}
|
|
479
|
+
function isSameInitOptions(existing, options) {
|
|
480
|
+
return existing.usdt.address === options.usdt.address;
|
|
481
|
+
}
|
|
482
|
+
function initWalletSdk(options) {
|
|
483
|
+
const existing = getStoredConfig();
|
|
484
|
+
if (existing && isSameInitOptions(existing, options)) {
|
|
485
|
+
return existing;
|
|
486
|
+
}
|
|
487
|
+
const config = buildConfig(options);
|
|
488
|
+
storeConfig(config);
|
|
489
|
+
return config;
|
|
490
|
+
}
|
|
491
|
+
function getWalletSdkConfig() {
|
|
492
|
+
const config = getStoredConfig();
|
|
493
|
+
if (!config) {
|
|
494
|
+
throw new Error("[wallet-sdk] initWalletSdk() must be called before using the library");
|
|
495
|
+
}
|
|
496
|
+
return config;
|
|
497
|
+
}
|
|
498
|
+
function isWalletSdkInitialized() {
|
|
499
|
+
return isStoredInitialized() && getStoredConfig() !== null;
|
|
500
|
+
}
|
|
501
|
+
function resetWalletSdkConfig() {
|
|
502
|
+
const globalState = globalThis;
|
|
503
|
+
delete globalState[CONFIG_KEY];
|
|
504
|
+
delete globalState[INITIALIZED_KEY];
|
|
505
|
+
clearJsonRpcReadProviderCache();
|
|
506
|
+
}
|
|
507
|
+
var walletReadProvider = null;
|
|
508
|
+
function setWalletReadProvider(provider) {
|
|
509
|
+
walletReadProvider = provider;
|
|
510
|
+
}
|
|
511
|
+
function refreshWalletReadProvider(eip1193) {
|
|
512
|
+
if (!walletReadProvider) return;
|
|
513
|
+
resetSharedBrowserProvider(eip1193);
|
|
514
|
+
walletReadProvider = getSharedBrowserProvider(eip1193);
|
|
515
|
+
}
|
|
516
|
+
function getConfiguredReadProvider(options = {}) {
|
|
517
|
+
if (walletReadProvider) {
|
|
518
|
+
return walletReadProvider;
|
|
519
|
+
}
|
|
520
|
+
if (!options.chainId) {
|
|
521
|
+
throw new Error(
|
|
522
|
+
"[wallet-sdk] Wallet read provider is not available. Connect wallet first or pass chainId for RPC read."
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
const chain = resolveChainConfig(options.chainId);
|
|
526
|
+
return getReadProviderWithFallback(null, chain, jsonRpcReadProviderCache);
|
|
527
|
+
}
|
|
528
|
+
async function isContractDeployed(contractAddress) {
|
|
529
|
+
return hasDeployedContract(getConfiguredReadProvider(), contractAddress);
|
|
530
|
+
}
|
|
531
|
+
async function getContractDecimals(contractAddress, options) {
|
|
532
|
+
const readProvider = getConfiguredReadProvider();
|
|
533
|
+
if (!await hasDeployedContract(readProvider, contractAddress)) {
|
|
534
|
+
throw new Error(`[wallet-sdk] Contract not deployed: ${contractAddress}`);
|
|
535
|
+
}
|
|
536
|
+
const tokenContract = new Contract(contractAddress, options.abi, readProvider);
|
|
537
|
+
const decimals = await tokenContract.getFunction(options.method).staticCall();
|
|
538
|
+
return Number(decimals);
|
|
539
|
+
}
|
|
540
|
+
async function getContractPrice(contractAddress, options) {
|
|
541
|
+
const readProvider = getConfiguredReadProvider();
|
|
542
|
+
if (!await hasDeployedContract(readProvider, contractAddress)) {
|
|
543
|
+
throw new Error(`[wallet-sdk] Contract not deployed: ${contractAddress}`);
|
|
544
|
+
}
|
|
545
|
+
const tokenContract = new Contract(contractAddress, options.abi, readProvider);
|
|
546
|
+
const price = await tokenContract.getFunction(options.method).staticCall();
|
|
547
|
+
const decimals = await getContractDecimals(contractAddress, { abi: options.abi, method: "decimals" });
|
|
548
|
+
return formatUnits(price, decimals);
|
|
549
|
+
}
|
|
550
|
+
async function readConfiguredUsdtDecimals(chainId) {
|
|
551
|
+
const { usdt } = getWalletSdkConfig();
|
|
552
|
+
return readErc20Decimals(getConfiguredReadProvider({ chainId }), usdt.address, usdt.abi);
|
|
553
|
+
}
|
|
554
|
+
async function readUsdtBalance(accountAddress, chainId) {
|
|
555
|
+
const { usdt } = getWalletSdkConfig();
|
|
556
|
+
return readErc20Balance(getConfiguredReadProvider({ chainId }), usdt.address, accountAddress, usdt.abi);
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/wallet/common.ts
|
|
560
|
+
function bindBrowserProvider(eip1193, cache) {
|
|
561
|
+
const nextProvider = getSharedBrowserProvider(eip1193);
|
|
562
|
+
if (cache.value !== nextProvider) {
|
|
563
|
+
cache.value = nextProvider;
|
|
564
|
+
}
|
|
565
|
+
return nextProvider;
|
|
566
|
+
}
|
|
567
|
+
async function requestWallet(eip1193, method, params) {
|
|
568
|
+
return eip1193.request({
|
|
569
|
+
method,
|
|
570
|
+
...params === void 0 ? {} : { params }
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
async function connectWalletAccount(requestAccounts, getProvider, setSigner, markConnected) {
|
|
574
|
+
const accounts = await requestAccounts() || [];
|
|
575
|
+
if (!accounts.length) {
|
|
576
|
+
throw new Error("No accounts returned");
|
|
577
|
+
}
|
|
578
|
+
const sourceProvider = getProvider();
|
|
579
|
+
const nextSigner = await sourceProvider.getSigner();
|
|
580
|
+
const address = await nextSigner.getAddress();
|
|
581
|
+
setSigner(nextSigner);
|
|
582
|
+
markConnected();
|
|
583
|
+
return { address, signer: nextSigner };
|
|
584
|
+
}
|
|
585
|
+
async function syncWalletAccountAddress(getProvider, setSigner, markConnected, nextAddress) {
|
|
586
|
+
const sourceProvider = getProvider();
|
|
587
|
+
const nextSigner = nextAddress ? await sourceProvider.getSigner(nextAddress) : await sourceProvider.getSigner();
|
|
588
|
+
const address = nextAddress || await nextSigner.getAddress();
|
|
589
|
+
setSigner(nextSigner);
|
|
590
|
+
markConnected();
|
|
591
|
+
return { address, signer: nextSigner };
|
|
592
|
+
}
|
|
593
|
+
function clearWalletRuntime(cache) {
|
|
594
|
+
cache.provider.value = null;
|
|
595
|
+
cache.signer.value = null;
|
|
596
|
+
if (cache.selectedProvider) {
|
|
597
|
+
cache.selectedProvider.value = null;
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// src/wallet/resolve-wallet-key.ts
|
|
602
|
+
function resolveWalletKey(provider) {
|
|
603
|
+
if (!provider) {
|
|
604
|
+
return "unknown";
|
|
605
|
+
}
|
|
606
|
+
const injected = provider;
|
|
607
|
+
if (injected.isTronLink || injected.isTronLinkWallet) {
|
|
608
|
+
return "tronlink";
|
|
609
|
+
}
|
|
610
|
+
if (injected.isCoinbaseWallet) {
|
|
611
|
+
return "coinbase";
|
|
612
|
+
}
|
|
613
|
+
if (injected.isTokenPocket) {
|
|
614
|
+
return "tokenpocket";
|
|
615
|
+
}
|
|
616
|
+
if (injected.isMetaMask) {
|
|
617
|
+
return "metamask";
|
|
618
|
+
}
|
|
619
|
+
if (typeof window !== "undefined") {
|
|
620
|
+
if (provider === window.tronLink || provider === window.tron) {
|
|
621
|
+
return "tronlink";
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
return "unknown";
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// src/wallet/wallet-event-adapters.ts
|
|
628
|
+
function normalizeAccountList(raw) {
|
|
629
|
+
if (Array.isArray(raw)) {
|
|
630
|
+
return raw.filter((item) => typeof item === "string" && item.length > 0);
|
|
631
|
+
}
|
|
632
|
+
if (typeof raw === "string" && raw.length > 0) {
|
|
633
|
+
return [raw];
|
|
634
|
+
}
|
|
635
|
+
return [];
|
|
636
|
+
}
|
|
637
|
+
function parseChainId(raw) {
|
|
638
|
+
if (typeof raw === "string") {
|
|
639
|
+
return raw;
|
|
640
|
+
}
|
|
641
|
+
if (raw && typeof raw === "object" && "chainId" in raw) {
|
|
642
|
+
return String(raw.chainId ?? "");
|
|
643
|
+
}
|
|
644
|
+
return String(raw ?? "");
|
|
645
|
+
}
|
|
646
|
+
function parseMetaMaskAccountsChanged(args) {
|
|
647
|
+
return {
|
|
648
|
+
name: "accountsChanged",
|
|
649
|
+
payload: normalizeAccountList(args[0]),
|
|
650
|
+
raw: args
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
function parseMetaMaskChainChanged(args) {
|
|
654
|
+
return {
|
|
655
|
+
name: "chainChanged",
|
|
656
|
+
payload: parseChainId(args[0]),
|
|
657
|
+
raw: args
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
function parseTronLinkAccountsChanged(args) {
|
|
661
|
+
return {
|
|
662
|
+
name: "accountsChanged",
|
|
663
|
+
payload: normalizeAccountList(args[0]),
|
|
664
|
+
raw: args
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
function parseTronLinkChainChanged(args) {
|
|
668
|
+
return {
|
|
669
|
+
name: "chainChanged",
|
|
670
|
+
payload: parseChainId(args[0]),
|
|
671
|
+
raw: args
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function parseTronLinkLegacyMessage(data) {
|
|
675
|
+
const message = data?.message;
|
|
676
|
+
if (!message?.action) {
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
if (message.action === "setAccount" && message.data?.address) {
|
|
680
|
+
return {
|
|
681
|
+
name: "setAccount",
|
|
682
|
+
payload: [message.data.address],
|
|
683
|
+
raw: [data]
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
if (message.action === "accountsChanged") {
|
|
687
|
+
const payload = normalizeAccountList(message.data);
|
|
688
|
+
return {
|
|
689
|
+
name: "accountsChanged",
|
|
690
|
+
payload,
|
|
691
|
+
raw: [data]
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
if (message.action === "disconnectWeb") {
|
|
695
|
+
return {
|
|
696
|
+
name: "disconnectWeb",
|
|
697
|
+
payload: [],
|
|
698
|
+
raw: [data]
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
return null;
|
|
702
|
+
}
|
|
703
|
+
var DEFAULT_RETRY = {
|
|
704
|
+
emptyAccountsRetryAttempts: 0,
|
|
705
|
+
emptyAccountsRetryIntervalMs: 0
|
|
706
|
+
};
|
|
707
|
+
var TRONLINK_RETRY = {
|
|
708
|
+
emptyAccountsRetryAttempts: 5,
|
|
709
|
+
emptyAccountsRetryIntervalMs: 120
|
|
710
|
+
};
|
|
711
|
+
var walletEventAdapters = {
|
|
712
|
+
metamask: {
|
|
713
|
+
parseAccountsChanged: parseMetaMaskAccountsChanged,
|
|
714
|
+
parseChainChanged: parseMetaMaskChainChanged,
|
|
715
|
+
...DEFAULT_RETRY
|
|
716
|
+
},
|
|
717
|
+
coinbase: {
|
|
718
|
+
parseAccountsChanged: parseMetaMaskAccountsChanged,
|
|
719
|
+
parseChainChanged: parseMetaMaskChainChanged,
|
|
720
|
+
...DEFAULT_RETRY
|
|
721
|
+
},
|
|
722
|
+
tokenpocket: {
|
|
723
|
+
parseAccountsChanged: parseMetaMaskAccountsChanged,
|
|
724
|
+
parseChainChanged: parseMetaMaskChainChanged,
|
|
725
|
+
...DEFAULT_RETRY
|
|
726
|
+
},
|
|
727
|
+
tronlink: {
|
|
728
|
+
parseAccountsChanged: parseTronLinkAccountsChanged,
|
|
729
|
+
parseChainChanged: parseTronLinkChainChanged,
|
|
730
|
+
parseLegacyMessage: parseTronLinkLegacyMessage,
|
|
731
|
+
...TRONLINK_RETRY
|
|
732
|
+
},
|
|
733
|
+
unknown: {
|
|
734
|
+
parseAccountsChanged: parseMetaMaskAccountsChanged,
|
|
735
|
+
parseChainChanged: parseMetaMaskChainChanged,
|
|
736
|
+
emptyAccountsRetryAttempts: 2,
|
|
737
|
+
emptyAccountsRetryIntervalMs: 100
|
|
738
|
+
}
|
|
739
|
+
};
|
|
740
|
+
function getWalletEventAdapter(wallet) {
|
|
741
|
+
return walletEventAdapters[wallet];
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// src/wallet/events.ts
|
|
745
|
+
var eventHandlers = {};
|
|
746
|
+
var providerBridges = /* @__PURE__ */ new WeakMap();
|
|
747
|
+
var walletEventProvider = null;
|
|
748
|
+
var boundProvider = null;
|
|
749
|
+
var activeWalletKey = "unknown";
|
|
750
|
+
var tronLinkMessageListener = null;
|
|
751
|
+
function dispatch(sdkEvent, wallet, event) {
|
|
752
|
+
const handlers = eventHandlers[sdkEvent];
|
|
753
|
+
if (!handlers) return;
|
|
754
|
+
for (const handler of handlers) {
|
|
755
|
+
void handler(wallet, event);
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
function emitWalletEvent(sdkEvent, wallet, event) {
|
|
759
|
+
dispatch(sdkEvent, wallet, event);
|
|
760
|
+
}
|
|
761
|
+
function unbindProvider(provider) {
|
|
762
|
+
const bridgeHandlers = providerBridges.get(provider);
|
|
763
|
+
if (!bridgeHandlers) return;
|
|
764
|
+
if (bridgeHandlers.accountsChanged) {
|
|
765
|
+
provider.removeListener("accountsChanged", bridgeHandlers.accountsChanged);
|
|
766
|
+
}
|
|
767
|
+
if (bridgeHandlers.chainChanged) {
|
|
768
|
+
provider.removeListener("chainChanged", bridgeHandlers.chainChanged);
|
|
769
|
+
}
|
|
770
|
+
providerBridges.delete(provider);
|
|
771
|
+
}
|
|
772
|
+
function unbindTronLinkLegacyMessages() {
|
|
773
|
+
if (!isBrowser || !tronLinkMessageListener) {
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
window.removeEventListener("message", tronLinkMessageListener);
|
|
777
|
+
tronLinkMessageListener = null;
|
|
778
|
+
}
|
|
779
|
+
async function handleAccountsChanged(wallet, nativeEvent) {
|
|
780
|
+
const { applyWalletAccountsChangedEffect } = await import('./account-sync-77HMBIWC.js');
|
|
781
|
+
await applyWalletAccountsChangedEffect(wallet, nativeEvent.payload);
|
|
782
|
+
dispatch("accountsChanged", wallet, nativeEvent);
|
|
783
|
+
}
|
|
784
|
+
function bindTronLinkLegacyMessages(wallet) {
|
|
785
|
+
if (!isBrowser || wallet !== "tronlink" || tronLinkMessageListener) {
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
const adapter = getWalletEventAdapter(wallet);
|
|
789
|
+
tronLinkMessageListener = (messageEvent) => {
|
|
790
|
+
if (!adapter.parseLegacyMessage) {
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
const parsed = adapter.parseLegacyMessage(messageEvent.data);
|
|
794
|
+
if (!parsed) {
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
if (parsed.name === "disconnectWeb") {
|
|
798
|
+
void handleAccountsChanged(wallet, parsed);
|
|
799
|
+
return;
|
|
800
|
+
}
|
|
801
|
+
if (parsed.payload.length > 0 || parsed.name === "accountsChanged") {
|
|
802
|
+
void handleAccountsChanged(wallet, parsed);
|
|
803
|
+
}
|
|
804
|
+
};
|
|
805
|
+
window.addEventListener("message", tronLinkMessageListener);
|
|
806
|
+
}
|
|
807
|
+
function syncProviderBinding() {
|
|
808
|
+
if (boundProvider) {
|
|
809
|
+
unbindProvider(boundProvider);
|
|
810
|
+
boundProvider = null;
|
|
811
|
+
}
|
|
812
|
+
unbindTronLinkLegacyMessages();
|
|
813
|
+
if (!walletEventProvider) {
|
|
814
|
+
activeWalletKey = "unknown";
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
activeWalletKey = resolveWalletKey(walletEventProvider);
|
|
818
|
+
const adapter = getWalletEventAdapter(activeWalletKey);
|
|
819
|
+
const bridgeHandlers = {};
|
|
820
|
+
if (eventHandlers.accountsChanged?.size) {
|
|
821
|
+
bridgeHandlers.accountsChanged = (...args) => {
|
|
822
|
+
const nativeEvent = adapter.parseAccountsChanged(args);
|
|
823
|
+
void handleAccountsChanged(activeWalletKey, nativeEvent);
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
if (eventHandlers.chainChanged?.size) {
|
|
827
|
+
bridgeHandlers.chainChanged = (...args) => {
|
|
828
|
+
if (walletEventProvider) {
|
|
829
|
+
refreshWalletReadProvider(walletEventProvider);
|
|
830
|
+
}
|
|
831
|
+
const nativeEvent = adapter.parseChainChanged(args);
|
|
832
|
+
dispatch("chainChanged", activeWalletKey, nativeEvent);
|
|
833
|
+
};
|
|
834
|
+
}
|
|
835
|
+
if (bridgeHandlers.accountsChanged) {
|
|
836
|
+
walletEventProvider.removeListener("accountsChanged", bridgeHandlers.accountsChanged);
|
|
837
|
+
walletEventProvider.on("accountsChanged", bridgeHandlers.accountsChanged);
|
|
838
|
+
}
|
|
839
|
+
if (bridgeHandlers.chainChanged) {
|
|
840
|
+
walletEventProvider.removeListener("chainChanged", bridgeHandlers.chainChanged);
|
|
841
|
+
walletEventProvider.on("chainChanged", bridgeHandlers.chainChanged);
|
|
842
|
+
}
|
|
843
|
+
providerBridges.set(walletEventProvider, bridgeHandlers);
|
|
844
|
+
boundProvider = walletEventProvider;
|
|
845
|
+
bindTronLinkLegacyMessages(activeWalletKey);
|
|
846
|
+
}
|
|
847
|
+
function setWalletEventProvider(provider) {
|
|
848
|
+
walletEventProvider = provider;
|
|
849
|
+
syncProviderBinding();
|
|
850
|
+
}
|
|
851
|
+
function getWalletEventProvider() {
|
|
852
|
+
if (!walletEventProvider) {
|
|
853
|
+
throw new Error("[wallet-sdk] Wallet event provider is not set");
|
|
854
|
+
}
|
|
855
|
+
return walletEventProvider;
|
|
856
|
+
}
|
|
857
|
+
function getActiveWalletKey() {
|
|
858
|
+
return activeWalletKey;
|
|
859
|
+
}
|
|
860
|
+
function registerEvent(event, listener) {
|
|
861
|
+
assertBrowser("walletEvents.on");
|
|
862
|
+
if (!eventHandlers[event]) {
|
|
863
|
+
eventHandlers[event] = /* @__PURE__ */ new Set();
|
|
864
|
+
}
|
|
865
|
+
eventHandlers[event].add(listener);
|
|
866
|
+
syncProviderBinding();
|
|
867
|
+
}
|
|
868
|
+
function unregisterEvent(event, listener) {
|
|
869
|
+
if (!isBrowser) return;
|
|
870
|
+
if (listener) {
|
|
871
|
+
eventHandlers[event]?.delete(listener);
|
|
872
|
+
} else {
|
|
873
|
+
eventHandlers[event]?.clear();
|
|
874
|
+
}
|
|
875
|
+
syncProviderBinding();
|
|
876
|
+
}
|
|
877
|
+
function clearEvents() {
|
|
878
|
+
if (!isBrowser) return;
|
|
879
|
+
for (const event of Object.keys(eventHandlers)) {
|
|
880
|
+
eventHandlers[event]?.clear();
|
|
881
|
+
}
|
|
882
|
+
syncProviderBinding();
|
|
883
|
+
}
|
|
884
|
+
var WalletEvents = class {
|
|
885
|
+
on(event, listener) {
|
|
886
|
+
registerEvent(event, listener);
|
|
887
|
+
}
|
|
888
|
+
off(event, listener) {
|
|
889
|
+
unregisterEvent(event, listener);
|
|
890
|
+
}
|
|
891
|
+
clear() {
|
|
892
|
+
clearEvents();
|
|
893
|
+
}
|
|
894
|
+
};
|
|
895
|
+
var walletEvents = new WalletEvents();
|
|
896
|
+
|
|
897
|
+
// src/wallet/runtime.ts
|
|
898
|
+
var RUNTIME_KEY = "__WALLET_SDK_RUNTIME__";
|
|
899
|
+
function getRuntimeStore() {
|
|
900
|
+
const globalState = globalThis;
|
|
901
|
+
if (!globalState[RUNTIME_KEY]) {
|
|
902
|
+
globalState[RUNTIME_KEY] = {
|
|
903
|
+
provider: null,
|
|
904
|
+
signer: null,
|
|
905
|
+
selectedProvider: null,
|
|
906
|
+
connected: false,
|
|
907
|
+
connectionSession: 0
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
return globalState[RUNTIME_KEY];
|
|
911
|
+
}
|
|
912
|
+
function invalidateConnectionSession(runtime) {
|
|
913
|
+
runtime.connectionSession += 1;
|
|
914
|
+
}
|
|
915
|
+
function isActiveConnectionSession(runtime, session) {
|
|
916
|
+
return runtime.connectionSession === session && runtime.selectedProvider !== null;
|
|
917
|
+
}
|
|
918
|
+
function isWalletConnected() {
|
|
919
|
+
const runtime = getRuntimeStore();
|
|
920
|
+
return runtime.connected && runtime.signer !== null && runtime.selectedProvider !== null;
|
|
921
|
+
}
|
|
922
|
+
function getWalletSigner() {
|
|
923
|
+
const signer = getRuntimeStore().signer;
|
|
924
|
+
if (!signer) {
|
|
925
|
+
throw new Error("[wallet-sdk] Wallet is not connected");
|
|
926
|
+
}
|
|
927
|
+
return signer;
|
|
928
|
+
}
|
|
929
|
+
async function getConnectedAddress() {
|
|
930
|
+
return getWalletSigner().getAddress();
|
|
931
|
+
}
|
|
932
|
+
function getSelectedWalletProvider() {
|
|
933
|
+
return getRuntimeStore().selectedProvider;
|
|
934
|
+
}
|
|
935
|
+
function getWalletBrowserProvider() {
|
|
936
|
+
return getRuntimeStore().provider;
|
|
937
|
+
}
|
|
938
|
+
function bindWalletProvider(eip1193) {
|
|
939
|
+
const runtime = getRuntimeStore();
|
|
940
|
+
invalidateConnectionSession(runtime);
|
|
941
|
+
runtime.selectedProvider = eip1193;
|
|
942
|
+
setWalletEventProvider(eip1193);
|
|
943
|
+
const browserProvider = getSharedBrowserProvider(eip1193);
|
|
944
|
+
runtime.provider = browserProvider;
|
|
945
|
+
setWalletReadProvider(browserProvider);
|
|
946
|
+
return browserProvider;
|
|
947
|
+
}
|
|
948
|
+
function syncWalletRuntimeProvider() {
|
|
949
|
+
const runtime = getRuntimeStore();
|
|
950
|
+
if (!runtime.selectedProvider) return;
|
|
951
|
+
refreshWalletReadProvider(runtime.selectedProvider);
|
|
952
|
+
runtime.provider = getSharedBrowserProvider(runtime.selectedProvider);
|
|
953
|
+
}
|
|
954
|
+
async function connectWallet(eip1193, options = {}) {
|
|
955
|
+
bindWalletProvider(eip1193);
|
|
956
|
+
const runtime = getRuntimeStore();
|
|
957
|
+
const session = runtime.connectionSession;
|
|
958
|
+
const result = await connectWalletAccount(
|
|
959
|
+
() => requestWallet(eip1193, "eth_requestAccounts"),
|
|
960
|
+
() => {
|
|
961
|
+
const provider = getRuntimeStore().provider;
|
|
962
|
+
if (!provider) {
|
|
963
|
+
throw new Error("[wallet-sdk] Wallet provider is not bound");
|
|
964
|
+
}
|
|
965
|
+
return provider;
|
|
966
|
+
},
|
|
967
|
+
(signer) => {
|
|
968
|
+
if (!isActiveConnectionSession(runtime, session)) return;
|
|
969
|
+
runtime.signer = signer;
|
|
970
|
+
},
|
|
971
|
+
() => {
|
|
972
|
+
if (!isActiveConnectionSession(runtime, session)) return;
|
|
973
|
+
runtime.connected = true;
|
|
974
|
+
}
|
|
975
|
+
);
|
|
976
|
+
if (options.chainId && isActiveConnectionSession(runtime, session)) {
|
|
977
|
+
const { switchToConfiguredNetwork } = await import('./network-WJN3S7KB.js');
|
|
978
|
+
await switchToConfiguredNetwork(options.chainId);
|
|
979
|
+
}
|
|
980
|
+
return result;
|
|
981
|
+
}
|
|
982
|
+
async function syncConnectedWalletAccount(nextAddress) {
|
|
983
|
+
const runtime = getRuntimeStore();
|
|
984
|
+
const session = runtime.connectionSession;
|
|
985
|
+
if (!runtime.provider) {
|
|
986
|
+
throw new Error("[wallet-sdk] Wallet provider is not bound");
|
|
987
|
+
}
|
|
988
|
+
return syncWalletAccountAddress(
|
|
989
|
+
() => {
|
|
990
|
+
if (!isActiveConnectionSession(runtime, session) || !runtime.provider) {
|
|
991
|
+
throw new Error("[wallet-sdk] Wallet disconnected during account sync");
|
|
992
|
+
}
|
|
993
|
+
return runtime.provider;
|
|
994
|
+
},
|
|
995
|
+
(signer) => {
|
|
996
|
+
if (!isActiveConnectionSession(runtime, session)) return;
|
|
997
|
+
runtime.signer = signer;
|
|
998
|
+
},
|
|
999
|
+
() => {
|
|
1000
|
+
if (!isActiveConnectionSession(runtime, session)) return;
|
|
1001
|
+
runtime.connected = true;
|
|
1002
|
+
},
|
|
1003
|
+
nextAddress
|
|
1004
|
+
);
|
|
1005
|
+
}
|
|
1006
|
+
function normalizeWalletAccounts(raw) {
|
|
1007
|
+
if (!Array.isArray(raw)) return [];
|
|
1008
|
+
return raw.filter((item) => typeof item === "string" && item.length > 0);
|
|
1009
|
+
}
|
|
1010
|
+
async function getWalletAccounts() {
|
|
1011
|
+
const provider = getSelectedWalletProvider();
|
|
1012
|
+
if (!provider) {
|
|
1013
|
+
throw new Error("[wallet-sdk] Wallet is not connected");
|
|
1014
|
+
}
|
|
1015
|
+
return normalizeWalletAccounts(await requestWallet(provider, "eth_accounts"));
|
|
1016
|
+
}
|
|
1017
|
+
async function tryRequestAccountPermissions(provider) {
|
|
1018
|
+
try {
|
|
1019
|
+
await requestWallet(provider, "wallet_requestPermissions", [{ eth_accounts: {} }]);
|
|
1020
|
+
return true;
|
|
1021
|
+
} catch (err) {
|
|
1022
|
+
const error = err;
|
|
1023
|
+
if (error?.code === 4001) {
|
|
1024
|
+
throw err;
|
|
1025
|
+
}
|
|
1026
|
+
if (error?.code === 4200) {
|
|
1027
|
+
return false;
|
|
1028
|
+
}
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1032
|
+
async function refreshWalletAccounts() {
|
|
1033
|
+
const provider = getSelectedWalletProvider();
|
|
1034
|
+
if (!provider) {
|
|
1035
|
+
throw new Error("[wallet-sdk] Wallet is not connected");
|
|
1036
|
+
}
|
|
1037
|
+
const permissionRequested = await tryRequestAccountPermissions(provider);
|
|
1038
|
+
if (permissionRequested) {
|
|
1039
|
+
return normalizeWalletAccounts(await requestWallet(provider, "eth_accounts"));
|
|
1040
|
+
}
|
|
1041
|
+
return normalizeWalletAccounts(await requestWallet(provider, "eth_requestAccounts"));
|
|
1042
|
+
}
|
|
1043
|
+
async function switchWalletAccount(address) {
|
|
1044
|
+
if (!isWalletConnected()) {
|
|
1045
|
+
throw new Error("[wallet-sdk] Wallet is not connected");
|
|
1046
|
+
}
|
|
1047
|
+
const accounts = await getWalletAccounts();
|
|
1048
|
+
const target = address.toLowerCase();
|
|
1049
|
+
if (!accounts.some((item) => item.toLowerCase() === target)) {
|
|
1050
|
+
throw new Error(`[wallet-sdk] Address not available in connected wallet: ${address}`);
|
|
1051
|
+
}
|
|
1052
|
+
return syncConnectedWalletAccount(address);
|
|
1053
|
+
}
|
|
1054
|
+
function disconnectWallet() {
|
|
1055
|
+
const runtime = getRuntimeStore();
|
|
1056
|
+
invalidateConnectionSession(runtime);
|
|
1057
|
+
runtime.provider = null;
|
|
1058
|
+
runtime.signer = null;
|
|
1059
|
+
runtime.selectedProvider = null;
|
|
1060
|
+
runtime.connected = false;
|
|
1061
|
+
setWalletEventProvider(null);
|
|
1062
|
+
setWalletReadProvider(null);
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
export { BSC_NETWORK, BSC_TESTNET_NETWORK, ERC20_ABI, ERC20_DECIMALS, ERC20_DECIMALS_ABI, SUPPORTED_BSC_CHAIN_IDS, USDT_CONFIG, WalletEvents, assertBrowser, bindBrowserProvider, bindWalletProvider, clearJsonRpcReadProviderCache, clearWalletRuntime, connectWallet, connectWalletAccount, createJsonRpcReadProvider, disconnectWallet, emitWalletEvent, getActiveWalletKey, getConfiguredReadProvider, getConnectedAddress, getContractDecimals, getContractPrice, getReadProviderWithFallback, getSelectedWalletProvider, getSharedBrowserProvider, getWalletAccounts, getWalletBrowserProvider, getWalletEventAdapter, getWalletEventProvider, getWalletSdkConfig, getWalletSigner, hasDeployedContract, initWalletSdk, isBrowser, isContractDeployed, isWalletConnected, isWalletSdkInitialized, normalizeSupportedBscChainId, readConfiguredUsdtDecimals, readErc20Balance, readErc20Decimals, readUsdtBalance, refreshWalletAccounts, refreshWalletReadProvider, requestWallet, resetWalletSdkConfig, resolveChainConfig, resolveWalletKey, setWalletEventProvider, setWalletReadProvider, switchWalletAccount, syncConnectedWalletAccount, syncWalletAccountAddress, syncWalletRuntimeProvider, toChainIdDecimal, walletEvents };
|